If you are anxious to get going and feel comfortable exploring on your own,
begin by looking at the
JavaSourceFile class.
This is where you add the different parts of a Java source file to create a class.
Create a template class that creates an instance of a JavaSourceFile to begin.
Use the methods beginning with the prefix add
to add fields, methods, etc.
Use the methods beginning with the prefix set
to set the name of the class
or the name of the package the class will belong to.
Invoke the method named generate()
to write out your class.
If you are not quite up to jumping in without a net, let's explore each feature before looking
at the JavaSourceFile. First, there are two interfaces that define String constants.
JavaPrimitiveConstants
defines constants for each Java primitive data type, e.g. int
or double
.
JavaKeywordConstants
extends JavaPrimitiveConstants and adds constants for each of the Java reserved words.
Having these constants available serve two purposes. They are there for you to use
so that you don't misspell a keyword. They are also there for the generator to use.
Although the various primitive Java types are available as constant strings, you probably won't need them.
All the types you use or define will be instances of a
JavaType.
There are pre-built static instances for each of the primitive types (e.g. JavaType.INT_TYPE
).
There are also static instances for the commonly-used String
type (JavaType.STRING_TYPE)
and for the common return type void
(JavaType.VOID_TYPE).
All other Java types (classes) are also instances of JavaType
.
They can include existing class types or new type names you are creating and need to reference elsewhere.
You can use one of the constructors or the static typeFor()
method to create them.
It just so happens that you can use typeFor()
to return a primitive type, too.
Let's build on this. The next class we'll look at is
JavaIdentifier.
This class represents a Java identifier. Sometimes we call this a variable, but it's more than that.
An identifier has a name,
a type (really a JavaType
) and, if it is an array, the dimension of the array.
An identifier can be used to define a field, the name and return type for a method,
and the name and type for a formal parameter in a method definition. More on definitions in a bit.
When you type
int count
you are specifying a Java identifier, whatever the context. The JavaIdentifier
just formalizes it and puts that information into an object that can be used elsewhere by the generator.
For arrays, we are defining the dimension of the array, not the number of elements it holds.
The dimension tells how many pairs of square brackets ([]) to use.
Another Java concept that pops up everywhere is Java access control.
This includes the keywords public
, protected
, and private
along with the so-called package access or default access.
It should be obvious by now that we have a class to manage this, too, and it is named
JavaAccessModifier.
Once again, pre-build static instances (such as JavaAccessModifier.PUBLIC_ACCESS
) are available
along with a static lookup method (modifierFor()
) to get one.
So much for the nice, short overview. A few more features to go.
The Java Class Generator has a number of classes that are derived from a class named
JavaDefinition.
These subclasses are used to define the various parts of a Java source file.
This includes the Java source class or interface name,
a field within the class (i.e. a static or instance member variable), and
a constructor or a method within the class.
All of the definition classes have a large number of constructors to make it easy to
define a Java source element with as few lines of code as possible.
The most important part of a Java source file is the code it contains!
The stuff between the curly braces!
Your template classes will no doubt have a lot of literal code included with the
sections and names that you parameterize out.
Wherever you need to define a block of code, such as for a method definition, use a
CodeBuffer.
It contains a myriad of methods to append literal code to a buffer which can then be
extracted as a formatted String.
You can include comments in your code, too!
You control the indentation level with each line of code you add.
Blocks of code adopt the next indentation level.
You can control whether that opening curly brace appears at the end of the line or
on a line by itself.