What's new in J2SE 5.0?

Based on Joshua Bloch's on-line talk
  1. J2SE 5.0 (named Tiger) was released in October 2004. The release is focused along certain key themes, namely quality, monitoring and manageability, performance and scalability, ease of development and desktop client.
  2. A poem about Tiger written by Joshua Bloch is quoted below.
  3. Generics - provides compile-time type safety for collections and eliminates the drudgery of casting.
    
    The poem wrote:
    
    To the most despised cast
    We'll bid a fond farewell at last
    With generics' burning spear
    The need for cast will disappear
    

    When you use a java.util.List to hold Strings, you would always have to cast to String when getting a value out.

    List names = new ArrayList();
    ...
    String name = (String)names.get(idx);
    

    With generics, you can declare it a List<String> and the compiler can check that for you. It is used in a typesafe way and you don't have to cast when taking values out of the list. So the above example can be coded in this way:

    List<String> names = new ArrayList<String>();
    ...
    String name = names.get(idx);
    

    Note: the J2SE 5.0 compiler will check the type for you. The ClassCastException may not be likely to be thrown, and you don't need to cast it back when you need the element of the collection.

    One more example: Remove 4-letters words.

    Current code:
    
    static void expurgate(Collection c) {
        for (Iterator i = c.iterator(); i.hasNext(); ) {
            String s = (String) i.next();
            if(s.length() == 4)
                i.remove();
        }
    }
    
    Generics code
    static void expurgate(Collection<String> c) {
        for (Iterator<String> i = c.iterator(); i.hasNext(); )
            if (i.next().length() == 4)
                i.remove();
    }
    

    Java generics are strongly typed, so you can only call a method that is a member of the "bound" of the type parameter. So, for example, you could define a generic method:

     
        ....
        void f(T t) { 
           t.whatever(); 
        }
    
    and this will constrain the type parameter to be some subclass or subinterface of Foo. If Foo has a method whatever(), this will be allowed, and is statically typechecked and typesafe.

    For multiple bounds:

    <T extends Interface1 & Interface2>
    

    Note that & is used instead of ,(comma) to separate different type parameters.

    Return to top


  4. Enhanced for loop - eliminates the drudgery and error-proneness of iterators.
    
    The poem wrote:
    
    While Iterators have their uses
    They sometimes strangle us like nooses
    With enhanced-for's deadly ray
    Iterator's kept at bay
    

    The enhanced for loop (also known as "foreach") lets you iterate over collections and arrays without using iterators or index variables.

    Current code:
    
    void cancelAll(Collection c) { 
        for (Iterator i = c.iterator(); i.hasNext(); ) {
            TimerTask tt = (TimerTask) i.next();
            tt.cancel();
        }
    }
     
    The J2SE 5.0 code would be:
    
    void cancelAll(Collection c) {
        for (Object o : c)
            ((TimerTask)o).cancel();
    }
    
    The colon (:) is pronounced "in."
    
    or you can write it with two new features:
    
    void cancelAll(Collection<TimerTask> c) {
        for (TimerTask task : c)
            task.cancel();
    }
    

    Return to top


  5. Autoboxing/unboxing - eliminates the drudgery of manual conversion between primitive types (such as int) and wrapper types (such as Integer). For example,
    
    The poem wrote:
    
    When from collections ints are drawn
    Wrapper classes make us mourn
    When Tiger comes, we'll shed no tears
    We'll autobox them in the ears
    
    The J2SE 5.0 code:
    
    public class Freq {
        public static void main(String args[]) {
           Map<String, Integer> m = new TreeMap<String, Integer>();
           for (String word : args)
               Integer freq = m.get(word);
               m.put(word, (feq == null? 1 : freq + 1));
           System.out.println(m);
        }
    }
    
    The current code would be:
    
    public class Freq {
        private static final Integer ONE = new Integer(1);
    
        public static void main(String args[]) {
            Map m = new TreeMap();
    
            for (int i=0; i<args.length; i++) {
                Integer freq = (Integer) m.get(args[i]);
                m.put(args[i], (freq==null ? ONE :
                      new Integer(freq.intValue() + 1)));
            }
            System.out.println(m);
        }
    }
    

    Return to top


  6. Typesafe enums - provides all the well-known benefits of the Typesafe Enum pattern without the verbosity and the error-proneness.

    Note: The enum will be a keyword, so if you used it as an identifier in your old code, you'll have to change it in order to use -source 1.5.

    
    The poem wrote:
    
    The int-enum will soon be gone
    like a foe we've known too long
    With typesafe-enum's mighty power
    Our foe will bother us no more
    
    public enum Coin {
        penny(1), nickel(5), dime(10), quarter(25);
    
        Coin(int value) { this.value = value; }
    
        private final int value;
    
        public int value() { return value; }
    }
    public class CoinTest {
        public static void main(String[] args) {
            for (Coin c : Coin.values())
                System.out.println(c + ":   \t"
                      + c.value() +"ยข \t" + color(c));
        }
        private enum CoinColor { copper, nickel, silver }
        private static CoinColor color(Coin c) {
            switch(c) {
              case penny:   return CoinColor.copper;
              case nickel:  return CoinColor.nickel;
              case dime:
              case quarter: return CoinColor.silver;
              default: throw new AssertionError("Unknown coin: " + c);
            }
        }
    }
    

    See how the constant declarations invoke a constructor, passing in an int that represents the value in cents? And see how the value is stored in a private field with a public accessor? See how we declare another enum for the colors? See how we can switch on enum constants? This is very useful when you want to "add a method" to an enum class, but you can't modify the class for whatever reason.

    Actually, the new enums are more than mere structs in other languages. If you don't add any methods or fields, they're just "rich" typesafe enum constants. If you add methods or fields in, they are just full-fledged objects.

    Return to top


  7. Static import - lets you avoid qualifying static members with class names, without the shortcomings of the Constant Interface antipattern. For example:
    
    The poem wrote:
    
    And from the constant interface
    we shall inherit no disgrace
    With static import at our side,
    our joy will be unqualified
    
    public interface Promotion {
      public static final double MANAGER_RATE   = 0.59;
      public static final double SUPERVISER_RATE   = 0.35;
    }
    

    If you want to access Promotion interface, you class has to implement it. But in J2SE 5.0, you can import it in this way:

    import static whatever.sub.Promotion;
    
    class Test {
        public static void main(String[] args) {
            double extra_salary = MANAGER_RATE * current_salary;
            ...
        }
    }
    
    Note: Promotion may be a class. It is good for constants class design.
    

    Return to top


  8. Metadata - lets you avoid writing boilerplate code, by enabling tools to generate it from annotations in the source code. This leads to a "declarative" programming style where the programmer says what should be done and tools emit the code to do it. For example, define attributions and build tool to do it.
    
    The poem wrote:
    
    And as for noble metadata
    I'll have to sing its praises later
    Its uses are so numerous
    To give their due, I'd miss the bus
    
    public class Test { 
        @Somewhere public void someMethod() {
            ...
        }
        
    }
    
    The code will be generated by the @Somewhere annotation.
    

    It is also called "Program Annotation."

    Note that the metadata will not introduce any new language keyword. It makes clever use of existing "punctuation." To declare an annotation type:

       public @interface Foo { ... } 
    
    Here "@interface" means "annotation-type" (get it? a-t -> at -> @). Also, it looks like a javadoc tag.

    To annotate:

    @Copyright("Acme Inc") public static final int baz(...) {
        ...
    } 
    
  9. Java variable arguments are object arrays. The compiler assembles the array for you based on the argument list you pass to a method.
    public void aMethod(String... args) {
        for(String s : args) {
            System.out.println(s);
        }
    }
    
    The aMethod can be called in the following ways:
    
    aMethod("here","we","go"); //3 argument list
    aMethod("to","be","or","not","to","be"); //6 argument list
    
    Note that the compiler will translate the aMethod automatically as:
    
    aMethod(new String[] {"here","we","go"});
    aMethod(new String[] {"to","be","or","not","to","be"});
    
  10. The reflection APIs are being extended to handle enums,generics and annotations.
  11. J2SE 5.0 introduces revisions to the core XML platform, including XML 1.1, SAX 2.0 and DOM Level 3.
  12. 32-bit surrogate character support will be carefully added to the platform so the Java "char" will still remain at 16 bits.
  13. java.lang.StringBuilder is added in J2SE 5.0 It is an unsynchronized version of java.lang.StringBuffer. Because StringBuffer is a fully syncronized, it makes String concatenation fairly slow. Instances of StringBuilder are not safe for use by multiple threads. StringBuilder can be used to significantly improve performance for some applications.
  14. Two new look and feels: an XP look and feel and a Linus GTK 2.0 look and feel. The default look and feel (metal) has been updated.
  15. Program startup is improved.
  16. X.class will be of type Class.
  17. Easy of use functionality to JTable, etc.
  18. Many new APIs, like java.util.concurrent, which does for concurrency (to prevent deadlock) what the Java Collections Framework did for data structures.
  19. All of the "wrapper" classes like weak references and thread locals will be retrofitted to use generics. So will some APIs that return specified generics (for example, List).
  20. Tuples, which is a way to handle multiple return types, will be considered in the future version.
  21. const keyword will not be supported in J2SE 5.0 or later. It has been rated as a conserved keyword since J2SE 1.0. Use final instead.
  22. java.util.Date will keep same. It has a small change, It will implement Comparable<Date> instead of just Comparable. The Date class has a problem of mutation. When to change it? not know yet.
  23. delegates, defined in J++ and C#, will not be included in J2SE 5.0.
  24. Operator overloading will not be included in J2SE 5.0. More to come. Stay tuned.

A poem written by Joshua Bloch

Quote start:


Tiger, Tiger Burning Bright
Like a geek who works all night
What new-fangled bit or byte
Could ease the hacker's weary plight?

To the most despised cast
We'll bid a fond farewell at last
With generics' burning spear
The need for cast will disappear

While Iterators have their uses
They sometimes strangle us like nooses
With enhanced-for's deadly ray
Iterator's kept at bay

When from collections ints are drawn
Wrapper classes make us mourn
When Tiger comes, we'll shed no tears
We'll autobox them in the ears

The int-enum will soon be gone
like a foe we've known too long
With typesafe-enum's mighty power
Our foe will bother us no more

And from the constant interface
we shall inherit no disgrace
With static import at our side,
our joy will be unqualified

And as for noble metadata
I'll have to sing its praises later
Its uses are so numerous
To give their due, I'd miss the bus

Quote end.

Return to top


References

Early Drafts Proposals for J2SE 5.0

Draft for Generics

Pre-release Compiler Download

J2SE

Effective Java Programming Language Guide