JavaOne: Generics in Tiger (J2SE 1.5)


Adding Generics to the Java Programming Language (TS-3063)
, Gilad
Bracha

Everyone likes generics, as the packed hall can attested. I know
Kinman’s waiting for them. I didn’t “grow up” in the C++ world, so I
probably don’t have as great a longing for them (templates, in C++
talk) as some, but more compile type checking is always good.

Bracha’s got to be the smoothest Java guy there is. Gosling may
be The Java Guy, but Bracha must be the suave Java Guy. He’s
svelte, wears a well cut, double breasted suit, and he has a smooth,
laid back delivery style.

It should be noted that Bracha really only talked about using code
that has generic methods and field: he didn’t really address designing
APIs with generics. That’s a hairy topic touched on lightly below,
then more when I type up some other notes I have.

What are Generics?

Most people probably have a good idea,
but we’ll sum it up real quick anyhow. Simplistically, generics transform this, non-generic’ed code,

List someList = new LinkedList();
someList.add(new Integer(5));
Integer myInt = (Integer)someList.iterator().next();

into this, generic’ed code,

List<Integer> someList = new LinkedList<Integer>();

someList.add(new Integer(5));
Integer myInt = someList.iterator().next();

The points of difference are bolded.

Also note, that another Tiger feature, autoboxing would remove the need
for the new Integer(5) wrapper; you could just pass in 5. More on that in another post.

I’m not really going to spend anymore time on syntax as it’s pretty
straight forward, and not 100% finalized yet. There’s additional
syntax, but that’s the meat of it. As usual, the commentary is as
interesting as the actual technology, e.g.,

An inordinate amount of conversation occurred about square brackets
versus angled brackets. Square brackets didn’t parse for some reason,
so here we are.

Typing to Catch Errors

While the amount of typing required
isn’t really reduced (you have to type the stuff instead
of casting), the main benefit is compile time type checking; that is,
you can have the compiler help you avoid runtime

ClassCastExceptions in many cases.

Bracha made a little joke on this point,

This allows compilers to catch errors earlier. Some say you don’t
need this: if you’re using Java to fly an airplane, just bring your
parachutes.

Catching errors early on, i.e., when compiling, is one of the best
arguments for strong type checking (see Guido’s remarks at Artima.com
about Python’s loose type checking and unit tests for another
view). Astute readers will, of course, note that it’s also one of the
most hampering things to deal with in more run-time dynamic settings,
like most of J2EE, e.g., JMX.

More Meaningful Code

Also, there’s fact that the code
becomes more readable, and, in a sort of metaphysical sense (or is it
ontological? I always forget the distinction), more meaningful. A
non-generic’ed List is really a holder for

Objects: you may happen to put Integers into
it, but it’s “meaning” is to hold Objects. A generic’ed
List<Integer>‘s “meaning” is to hold integers;
there’s no confusion or ambiguity.

As Bracha put it, a generic’ed Collection is “telling
you something about the variable at the declaration point. That’s 90%
of generics right there.”

Migration

There was a lot of time spent going over how
migration concerns drove the requirements for generics. The problem in
a nut is that once you enable generics, you want your legacy code to
retain the same meaning as it had before; you can’t screw up legacy
code. Apparently, the “Global Software Tax Convention in Redmund,” as
Bracha called It, was ignoring this problem.

Desires for Migration Effects/Tasks

  • no duplication of code needed – must ship J2SE 1.4 and 1.5 libs.
  • no release coordination needed – you have to wait for a lib you
    depend on to go generic before you go generic.
  • migrate when you want – not forced to migrate your lib to
    generics at any given time because you upgrade to 1.5.

Essentially, we need backwards compatibility. To get this, we allow
the following type of code…though, it produces a compiler
warning,

public String loophole(Integer int) {
  List ys = new LinkedList();
  List xs = ys; // we loose the generic typing here
  xs.add(int); // warning, type is ambiguous
  return (String)xs.iterator().next(); // run time exception
}

As always, “don’t do that.” Bracha said that out of the million-odd of
lines of code in the JDK, there were only a couple of migration
problem spots: something having to do with
"".compareTo(Object), but I didn’t quite catch/understand
what he was saying.

When?!

There’s early
access code available now
; though, from the Bloch and Grafter’s
Thursday night BoF, many of the implementation details are still being
ironed out. For the more production code minded among us, it’ll be in
Tiger, J2SE 1.5, which is supposed to be released in about a year.

Designing APIs with Generics

I’m going to have to spend
some serious time mulling over the generics information I got from the
Grafter an Bloch BoF
; there are some major conceptual
hurdles to get over when it comes to coding generics properly in
APIs. Bloch said the nut of it is,

An Integer is a Number, but a

List of Integers is not a List
of Numbers.

I believe the two relevant terms are “variance” and
“co-variance.”

In the mean time, there’s a good article on
devx.com
on using Generics. Sadly, it doesn’t cover API design
with generics. More on that later.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.