A few months ago, Sun made available an early access compiler for JSR 14. JSR 14 adds Generics to the Java language, and will be available in full in JDK1.5.
The early-access compiler works by "wrapping" around the existing
JDK1.4 compiler, and comes with helper .sh
and
.bat
files. They work fine, but using those wrapper
scripts from within
Ant
wasn't the easiest thing in the world.
So I hacked together my own Ant compiler-adapter for this early access compiler, which you can download below.
(Make sure you read the caveats below.)
Generics allow parameterised types, or what are called templates in C++. You know what a type is; in Java it is a class. A parameterised type (or class) has one (or more) parameters; these parameters can modify the meaning of the type.
Take java.util.List
for example; it stores a list of
Object
s. Well, in a real program it rarely
stores actual instances of java.lang.Object
; you
usually fill it with a more useful subclass, like String
s.
And this is where a parameterised type comes in; it allows you to
add more information to you code, telling the compiler and other
coders what is actually inside your List
.
Time for a code example. I'm sure you've seen something like this before:
List someList = new LinkedList();
someList.add("item 1");
someList.add("item 2");
...
for (Iterator i = someList.iterator(); i.hasNext();) {
String str = (String) i.next();
System.out.println(str);
}
The "problem" with the above code is... how can you be sure
it's a String
when you cast the return value of
i.next()
? The answer is you can't; you just have
to trust the program has been coded right.
This changes under JDK1.5 and Generics:
ListsomeList = new LinkedList (); someList.add("item 1"); someList.add("item 2"); ... for (Iterator i = someList.iterator(); i.hasNext();) { String str = i.next(); System.out.println(str); }
As you can see by the emphasised parts, we declare what type of
List
it is using "angle bracket" notation, and we don't
need to do the cast. There are many more benefits to Generics, maybe
I'll talk about them another day.
Here are simple, step-by-step instructions for Generics-enabling your code with the JSR 14 early-access prototype and my Ant compiler adapter (see downloads below).
.zip
to your hard
drive somewhere.
jsr14adapter-1.x.jar
to your
ANT_HOME/lib
directory.
jsr14adapter-1.x.jar
in you
CLASSPATH
before running Ant.
jsr14.home
property to your Ant file.
com.madbean.Jsr14CompilerAdapter
:
build.compiler
property; or
compiler
attribute of the
<javac>
Ant task.
source="1.5"
on your
Ant task.
Suppose you have a run-of-the-mill Ant build file like this:
To Generics-enable your compilation, drop jsr14adapter-1.x.jar
into your
ANT_HOME/lib
directory, and make the following changes to
your Ant build file:
<project name="example" default="code">
<span class="egem"><property name="jsr14.home"
value="d:/opt/java/jsr14_adding_generics-1_3-ea"/></span>
<target name="code">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes"
<span class="egem">source="1.5"</span>
<span class="egem">compiler="com.madbean.Jsr14CompilerAdapter"</span>
/>
</target>
<target name="clean">
<delete dir="build"/>
</target>
</project>
* You need to replace
d:/opt/java/jsr14_adding_generics-1_3-ea
with the
directory where you extracted the JSR early-access download.
As always, your mileage may vary:
Since compiler setting isn't classic or modern,ignoring fork setting.
My Ant compiler-adapter:
ANT_HOME/lib
):
JSR 14/Generics