Today was the first real day of JavaOne.
I woke up, worked out, and got to the convention center in time to play a game or two of pinball before I went to the keynote. There are a bunch of pin, air hockey, and foos tables around, and one of the pins is a Twilight Zone, widely acknowledged to be the best pin that Williams ever produced. Ive been thinking about buying one, so it was good to have a chance to see if it was as good as I remembered. And, with a few exceptions (this pin had a sticky upper flipper, a lock that didnt always work, and it was on carpet so you couldnt do slide saves), it was pretty good. Hmm. Perhaps when the motorcycle sells.
I should state at the beginning that this is all from a Microsoft Guy perspective. Id appreciate any comments and/or corrections if you think Im off base.
The keynote this morning was a little bit uneven. Ill give some high and low points.
The Sun position ends up being somewhat strange. They dont want to alienate the other sponsors at the conference, but they also want to sell their stuff, so they go from talking about how great the community is to how great their stuff is.
Another big difference from TechEd is that most of the presentations are not done by program managers or marketing people. That has a potential to give a better connection to the real developers, but runs the risk of having presentations that are less than effective. I dont think they really succeeded in relating the things that they were doing to actual customer problems that needed to be solved.
New release of J2SE
I also attended a talk entitled, Fast Track to the JavaTM 2 Platform, Standard Edition (J2SETM) v5.0 (note that Sun is syncing their version numbers at 5.0) that covered some of the improvements in the new (codename Tiger) release. The language ones will be covered in more detail in a language talk that I go to later (6:00 7:15), and then later at a BOF session starting at 10:30PM (what *are* they thinking there are more sessions scheduled at this time than at any other time).
This was a hard talk to watch. With all of the cool stuff that is showing up in their new release, Id expect it to be easy to get applause from the crowd, but the talk didnt elicit any from the totally packed house (easily over 1000 people).
New Features in the JavaTM Programming Language
Gilad Bracha, computational theologist, Sun
Mads Torgersen, Aarhus University
I love the title computational theologist
This was a fairly entertaining talk, though the presenters started out by saying were tired of talking about all the new language features over and over, so were going to talk about two areas that we find interesting instead of covering everything.
Their justification for autoboxing is similar to the justification we used when adding it to C#, though Gilad said that he had been campaigning to add it for years, but that having C# exist made it easier to make things happen.
Java has always put types in two camps the primitive types, and objects. To bridge the gap, they have reference type wrappers, such as the Integer class, which wrap an int. This makes using lists of primitive types fairly painful.
Where in C#, we would write something like:
ArrayList a = new ArrayList();
foreach (int i in a)
int j = i;
Even though there is boxing going on there, its largely hidden from the user, and the model is fairly simple.
The Java equivalent is:
Arraylist a = new Arraylist();
Interator i = a.iterator();
while (i.hasNext() )
Integer val = (Integer) i.next();
int j = val.intValue;
Theyre trying to simplify this in Java 5.0, both through generics, and through the addition of autoboxing. Generics isnt enough by itself, as switching to an Arraylist<Integer> would only get rid of the cast in the call to next(), which isnt that much of an improvement. What they need is a way to make Integer and int interchangeable, which is what they do through their automatic invocation of boxing and unboxing.
The key difference between C# boxing and Java 5.0 boxing is that C# boxes between primitive types and object, and Java does it between primitive types and the predefined wrapper types. This allows them to do implicit conversions both directions (an Integer and an int are pretty close in behavior).
There are some issues on this that have to do with object identity. Consider the following:
Map m = new Map<Integer, String>();
string s = m.at(3);
What does the third line do? Well, it turns out that the two 3 values arent the same because they are autoboxed to different reference types. That behavior is a bit surprising.
To improve the situation, theyve come up with an interesting modification, which I believe this is not part of the standard, but part of javac.
They get around this and Im not making this up by playing tricks for small integer values, but not for large integer values. They did not give an exact description for how this behavior is controlled.
As one attendee stated after the talk, I like the idea of autoboxing, Id just like it to be consistent. I understand the problem that not having value type identify for the wrapper classes causes them and why theyre stuck with that, but to work around it a bit is a surprising choice, and probably a mistake.
Wildcards in generics
The second area the touched on is generic wildcards, which is an interesting and somewhat controversial addition to the Java 5.0 generic support.
This is best explained through an example, though Ill warn you at the outset that this is something Ive only looked at a couple of times, so the example may not be that great.
One of the disadvantages in some generic approaches (C# included) is that theres no way to express List<anything>. Well, actually, there is you can write:
But that has the side effect of only being runtime typesafe, which is normally not what you want. You can assign a List<Apple> to a list of object, but theres no compiler support to keep you from adding a Banana to that list.
Wildcards let you get around this. You can write:
As a type, and any list can be assigned to that type. This is pretty close to List<Object>, so to get what you want, you would typically do something like:
List<? extends Fruit> c;
Which means that c can be a list of anything, as long as that anything is a Fruit or somethng derived from that. That means I can now write:
c = new List<Bananas>();
and I can pull items of type Fruit out of list c. What I cant do is add items to c, because I might add an Apple to the list, which is clearly wrong, and therefore prohibited by the compiler. This compiler prohibition is one of the big points of supporting wildcards.
Wildcards can also be expressed as requiring a superclass:
List<? super Apple> d;
What does that mean? Well, it means that d can be a List<Apple>, or a List<Fruit>. On this list, I can safely add an Apple, because an Apple can happily exist in a List<Fruit>, but when I pull items out of the list, I can only pull them out as Object, because they aret forced to be apples.
So what does all of this give us? The first benefit is nicer signatures. I can write:
Void reverse(List<?> a)
Instead of writing:
Void reverse<T>(List<T> a)
I dont really see this as much of an advantage, especially since the way I implement the first one is by calling a private version of the second one.
The second advantage is that this syntax works where generic methods arent allowed in constructors, for example.
I dont think this are worth the additional complexity, especially on a language that has prided itself on simplicity. The presenters quote was, It does the thing you expect if you expect the right thing, which I think is a different philosophy that Java has advocated in the past.
Java 5.0 and C#
Many people have said that C# is a Java rip-off. While C# does draw from the experience of many languages, its interesting to look at the new Java language features that are showing up in V5.0.
Params / varargs
A few notes here.
On foreach, Java doesnt add a foreach keyword, but they do support the equivalent of foreach using the for keyword. Though I was interested to note that they referred to the feature as foreach even though they dont have that keyword.
Attributes (known as annotations in the Java space) actually have two purposes. They support a design-time only mode, where you write the annoation, and then run a tool that does code generation on top of your classes to generate the boilerplate code. In this scenario, the annotations dont end up in the metadata. And then there is another version in which the annotations do end up in the metadata.
On the generics front, one of the important design points for the Java version was that it run on all existing JVMs (ie its 1.4 compatible). Since their JVM isnt generic-aware, they dont get any of the performance benefits of having generics. There is still no way to do an efficient generic collection over a primitive type. While I understand the constraints (ha ha) under which they did their design, I think its unfortunate that developers will still have to make the decision between the efficiency of arrays and the convenience of collections in some cases. To be fair, this is still true in very perf-sensitive scenarios even with .NET generics, but this is a far smaller number of items. Another disadvantage is their limited support for finding out about a generic type through reflection,.