JavaOne: Day One


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.


High points

  • A nice video about how the community is what it is all about
  • Open sourcing Java3D
  • Open sourcing looking glass, a 3D longhorn-ish windowing system, real soon now.
  • An air-powered t-shirt cannon, controlled through a web browser. But it would have been better if they did a rich client interface (the client is back is one of the sayings from today), and could target a specific area of the room. 

Low points

  • Using BMWs iDrive system as an example of vibrant Java support for other kinds of devices. First of all, it took about 30 seconds for the system to boot up, and then the demo was less than inspiring. Car navigation systems arent terribly innovative right now, nor showing us an options page terribly exciting, especially when the demo delivery was totally devoid of passion. It doesnt help that IDrive has been universally panned by the automotive press as as a solution looking for a problem (not a comment on Java, just a reflection that buttons and sliders are a pretty good user interface).
  • Doing an audience applause thing to vote for the image on the new box of Java Studio Creator, but then not reporting the results.
  • A demo of a medical monitoring device that talks with a phone. Neat demo, neat concept, but the use of Java was fairly incidental.


Weird points

  • Kicking all the press out after the first part with, okay, now its time for all the press and analysts to go to room 123. Cmon, stand up and go.


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).


They claim:

  • Improvements in starting time, up to 50% on a minimal swing app. It looks like they may be doing something along the lines of ngen, but there wasnt enough detail to be sure.
  • Some new and interesting APIs for monitoring and debugging.
  • New look and feel support (I think in Swing, but I didnt write it down for sure), that can give you either XP-style, Apple style, or a new Java style named Ocean.


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();

a.Add(new Integer(1));

a.Add(new Integer(4));

a.Add(new Integer(9));


Interator i = a.iterator();

while (i.hasNext() )


            Integer val = (Integer);

            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>();

m.add(3, foo);

string s =;


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:


List<object> c;


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:


List<?>  c;


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.



C# 1.0

C# 2.0

Java 1.4

Java 5.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,.



Comments (20)

  1. Quaid says:

    Java version numbering – WTFrick!?

    I thought 1.5 was ‘Java 2.0’ (this being crazy in itself), but now the next version is ‘Java 5.0’.


  2. Nicholas Allen says:

    This is a great summary. There were a few things that caught my eye.

    In the new features section, it sounds like that talk really missed the audience.

    > Improvements in starting time

    I talked a little about that with Junfeng Zhang in the past. Somewhat similar but not quite the same as ngen.

    > New look and feel support

    Java has always had pluggable look and feels but there’s very few 3rd party ones available. Mostly it was considered too hard to be worth it. In addition to updating the old Metal style, this is supposed to make 3rd party L&F creation easy.

    > one of the important design points for the Java version was that it run on all existing JVMs (ie its 1.4 compatible)

    This isn’t true. If you use 1.5 language features, you’re forced to use a 1.5 VM. What they probably said was that code compiled for 1.4 had to work correctly when used with code compiled for 1.5 (and using generics). They support old code on new platforms (backward compat). They do not support new code on old platforms (forward compat).

  3. Nikolay Botev says:

    The following caught my attention and I really could not resist testing it out:

    >There are some issues on this that have to do >with object identity. Consider the following:



    >Map m = new Map<Integer, String>();

    >m.add(3, foo);

    >string s =;


    >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.

    I don’t know, maybe I’m doing something wrong, but this example (when all the errors are corrected) seems to work fine for me with large integers (maybe I’m not using a "real" large value?). I did uncover another problem though, but the point is – there doesn’t seem to be any "playing tricks with small integers". I wonder what the "magic" number is that Sun chose to separate the space of small ints from large ints :-D. I’m also interested to find out what the source of that information is.

    The code that I compiled and ran under the latest snapshot release of Java 5 is below.

    The problem I uncovered was when the key is of type Long and an int is used to retrieve the value. The value is not found and this only makes sense, however, this makes space for obscure bugs and should ideally either trigger a compile-time error or automatically autobox to Long instead of Integer.

    import java.util.Map;

    import java.util.HashMap;

    class testnum


    public static void main(String args[])


    Map<Integer, String> m = new HashMap<Integer, String>();

    m.put(3, "foo");

    String s = m.get(3);

    System.out.printf("First item: %sn", s);

    m.put(300400600, "boo");

    s = m.get(300400600);

    System.out.printf("Big item: %sn", s);

    m.put(2100400600, "woohaaa");

    s = m.get(2100400600);

    System.out.printf("Very big item: %sn", s);

    Map<Long, String> m2 = new HashMap<Long, String>();

    m2.put(9L, "smallee");

    s = m2.get(9L);

    System.out.printf("Long 1st item: %sn", s);

    s = m2.get(9); // auto-boxed to Integer?

    System.out.printf("Long 1st item problem!: %sn", s);

    m2.put(9223372036854775807L, "now this is crazy!");

    s = m2.get(9223372036854775807L);

    System.out.printf("It really doesn’t get any bigger than this: %sn", s);



  4. Eric,

    thanks for the summary. almost as good as beeing there in person… 🙂


    thomas woelfer

  5. Robert O'Callahan says:

    > Map m = new Map<Integer, String>();


    > m.add(3, foo);


    > String s =;

    This will work fine. The boxed versions of 3 may or may not be the same object, but they will be equal according to equals() and hashCode(). I think Mr Gunnerson is confused.

  6. Nicholas Allen says:

    Where it’ll break is IdentityHashMap or other code which uses == for identity instead of equals for identity. But we’ve lived through that long enough with strings and survived.

  7. Your C# foreach code can be done in 5.0 using the new for-construct "for (int i: a)" – not quite as easy to read/understand as c#’s foreach notation, but it essentially does the same thing and I can understand a reluctance to introduce new keywords.

    as others have noted, the Map example only breaks down when you use an IdentityHashMap, which is a fairly little used Map implementation that uses object equality instead of hashcode() and equals(). For more information on IdentityHashMap and some usage examples, check out the JavaDocs at

  8. Chad Myers says:

    As a former Java developer, it’s kinda sad to see Sun flailing around like this (implementing some new features, but only half-way or healt-heartedly) and trying to strike back at C# or something.

    Java started out so pure and straight-forward and I was proud to develop on it.

    But now whenever I have to go back and try to use it, I’m confounded by it’s lack of progress. It’s not very different now (1.4 or 5 ) than it was in the 1.3 days. Very little XML support (or chumpy support at that)… very little of anything. If you want to do anything useful with Java, you have to end up downloading 35 different 3rd-party libraries (most usually from Apache-Jakarta) and then enter into "Classpath Hell".

    It just leaves me scratching my head.

    On that note, excellent work on C# 1.x and 2.0 Eric and Team. I’m rarely left scratching my head on anything (well, unsafe stuff still confuses me, but you know what I mean).

  9. Jocelyn Coulmance says:

    > 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:

    > List<object> c;

    List<?> should not be read as "List of anything" (which is what List<object> conveys) but "any list of something".

    And yes, this is a feature I’d like to have in C#.

  10. Some interesting notes from a Microsoft attendee at JavaOne….

  11. John Harby says:

    Thanks for your insights, this is very interesting.

  12. Joe Cheng says:

    If I understand correctly, the "wildcards in generics" feature is better known elsewhere as covariance/contravariance.

  13. Stephen Leach says:

    I agree that the Java dev have made a crucial design decision here. Experimentation with Java 1.5/5.0 shows that very small integers box identically and large ones don’t. I also agree it is a mistake – it is a rerun of the String.intern() mistake.

  14. Bernhard Messerer says:

    Indeed, the spec says that this "small int trick" is done with byte-values: All byte values MUST be cached and thus will be boxed to the same ("==") integer (thus it even works with IdentityHashMap).

    For larger ints, behavior is unspecified, they may or may not be cached, in Sun’s implementation (JDK 1.5 Beta2) it will use Integer.valueOf(int), which caches "frequently used" values, so it should even work with larger numbers… no guarantee though…

    Note that it worked differently with Beta1, this one didn’t cache any values…

    Overally I agree, its a stupid decision as it draws a virtual limit within the language. Practically, it shouldn’t lead to many bugs, as objects should never be compared with "==".


    P.S.: I think they should have left the whole autoboxing "feature" out…

  15. Bernhard Messerer says:

    P.P.S.: What’s wrong with String.intern()?

    _Always_ compare objects with equals(), "==" checks for identity… Strings offer the ability to "cache" Strings at the JVM level via intern(), very good for often used strings… however, you’re not forced to use it…


  16. Channel 9 says:

    If by metadata u mean Attributes then the answer is not yet.