Java 1.5/5 New Features

Content:

  1. Version numbers
  2. Release
  3. Static import
  4. Auto boxing/unboxing
  5. Generics
  6. New for loop
  7. Type safe enums
  8. Scanner class
  9. Varargs
  10. Formatted output
  11. System.getenv
  12. StringBuilder class
  13. Concurrent utilities
  14. Annotations
  15. Class data sharing
  16. JMX

Version numbers:

This version is officially known as Java SE 5, but often called Java 1.5. It has codename Tiger.

Java version Official name Code name Release date
1.0 JDK 1.0 January 23rd 1996
1.1 JDK 1.1 February 19th 1997
1.2 J2SE 1.2 Playground December 8th 1998
1.3 J2SE 1.3 Kestrel May 8th 2000
1.4 J2SE 1.4 Merlin February 6th 2002
1.5/5 Java SE 5 Tiger September 30th 2004

Release:

Java 1.5 was released September 30th 2004.

Java 1.5 comes with a lot of new features in both language and library. It is likely the most important release since 1.0.

To use the new features remember to compile with:

To compile applets that will run with Microsofts old JVM compile with:

Static import:

Java 1.5 can do static import of a class, which allows referring to static members without specifying class name.

Previous:

public class SI14 {
   public static void main(String[] args) {
       System.out.println(Math.pow(2, 6));
   }
}

Now:

import static java.lang.Math.*;

public class SI15 {
   public static void main(String[] args) {
       System.out.println(pow(2, 6));
   }
}

Previous:

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class SIX14 extends JFrame {
    public SIX14() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(new JLabel("N"), BorderLayout.NORTH);
        getContentPane().add(new JLabel("W"), BorderLayout.WEST);
        getContentPane().add(new JLabel("E"), BorderLayout.EAST);
        getContentPane().add(new JLabel("S"), BorderLayout.SOUTH);
        pack();
    }
    public static void main(String[] args) {
        SIX14 f = new SIX14();
        f.setVisible(true);
    }
}

Now:

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;

import static java.awt.BorderLayout.*;

public class SIX15 extends JFrame {
    public SIX15() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(new JLabel("N"), NORTH);
        getContentPane().add(new JLabel("W"), WEST);
        getContentPane().add(new JLabel("E"), EAST);
        getContentPane().add(new JLabel("S"), SOUTH);
        pack();
    }
    public static void main(String[] args) {
        SIX15 f = new SIX15();
        f.setVisible(true);
    }
}

In my opinion a useful but not important feature.

I expect it to be used when it makes sense, which is rare.

Auto boxing/unboxing:

Java can now convert between simple data types and their corresponding wrapper reference types automatically.

This feature is known as auto boxing and auto unboxing. And it is known from C#.

Previous:

public class ABUB14 {
    public static void main(String[] args) {
        int i1 = 123;
        Integer i2 = new Integer(i1);
        System.out.println(i2);
        int i3 = i2.intValue();
        System.out.println(i3);
    }
}

Now:

public class ABUB15 {
    public static void main(String[] args) {
        int i1 = 123;
        Integer i2 = i1;
        System.out.println(i2);
        int i3 = i2;
        System.out.println(i3);
    }
}

I think this is avery useful feature as it makes the code much easier to read.

I think everybody will use it as it is so natural.

Generics:

Java 1.5 added the possibility for making classes/interfaces that operate on any type.

This feature is gnown as generics. And the concept is known from C++ (templates).

The concept behind Java generics and C++ templates are the same, but the implementation and practical characteristics are very different.

The most obvious usage is type safe collections.

Previous:

import java.util.ArrayList;
import java.util.List;

public class G14 {
    public static void main(String[] args) {
        List lst = new ArrayList();
        lst.add(new Integer(1));
        lst.add(new Integer(22));
        lst.add(new Integer(333));
        // this will give a runtime exception:
        // lst.add("abc");
        for(int i = 0; i < lst.size(); i++) {
            Integer v = (Integer)lst.get(i);
            System.out.println(v);
        }
    }
}

Now:

import java.util.ArrayList;
import java.util.List;

public class G15 {
    public static void main(String[] args) {
        List<Integer> lst = new ArrayList<Integer>();
        lst.add(new Integer(1));
        lst.add(new Integer(22));
        lst.add(new Integer(333));
        // this will give a compile error:
        // lst.add("abc");
        for(int i = 0; i < lst.size(); i++) {
            Integer v = lst.get(i);
            System.out.println(v);
        }
    }
}

Or if we combine with auto boxing and unboxing:

import java.util.ArrayList;
import java.util.List;

public class GX15 {
    public static void main(String[] args) {
        List<Integer> lst = new ArrayList<Integer>();
        lst.add(1);
        lst.add(22);
        lst.add(333);
        // this will give a compile error:
        // lst.add("abc");
        for(int i = 0; i < lst.size(); i++) {
            int v = lst.get(i);
            System.out.println(v);
        }
    }
}

Note that generics can also be used for other things than collections - collections are just the most obvious.

This is a very useful feature that reall improves type safety.

And I am sure it will be used a lot both for collections and for other things.

New for loop:

In Java 1.5 one can replace:

Iterator it = xxx.iterator();
while(it.hasNext()) {
   X v = (X)it.next();
   // something
}

with:

for(X v : xxx) {
   // something
}

This feature is known in many other languages like C# and PHP as a foreach loop.

Example also using generics and auto boxing/unboxing.

Previous:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class F14 {
    public static void main(String[] args) {
        Map m = new HashMap();
        m.put(new Integer(1), "a");
        m.put(new Integer(2), "bb");
        m.put(new Integer(3), "ccc");
        Iterator it = m.keySet().iterator();
        while(it.hasNext()) {
            Integer k = (Integer)it.next();
            String v = (String)m.get(k);
            System.out.println(k + " " + v);
        }
    }
}

Now:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class F15 {
    public static void main(String[] args) {
        Map<Integer,String> m = new HashMap<Integer,String>();
        m.put(1, "a");
        m.put(2, "bb");
        m.put(3, "ccc");
        for(int k : m.keySet()) {
            String v = m.get(k);
            System.out.println(k + " " + v);
        }
    }
}

Very useful when combined with generics and auto boxing/unboxing.

And I am sure that it will also be used.

Type safe enums:

Java 1.5 got enums and unlike C/C++ and C# in a type safe flavor.

Previous standard way:

public class E14std {
    public static final int C = 1;
    public static final int CPP = 2;
    public static final int CS = 3;
    public static final int JAVA = 4;
    public static String toString(int lang) {
        switch(lang) {
            case C:
                return "C";
            case CPP:
                return "CPP";
            case CS:
                return "CS";
            case JAVA:
                return "JAVA";
            default:
                return "Unknown";
        }
    }
    public static void main(String[] args) {
        int lang = E14std.JAVA;
        System.out.println(E14std.toString(E14std.JAVA));
    }
}

Previous smart way:

public class E14smart {
    private String name;
    private E14smart(String name) {
        this.name = name;
    }
    public String toString() {
        return name;
    }
    public static final E14smart C = new E14smart("C");
    public static final E14smart CPP = new E14smart("CPP");
    public static final E14smart CS = new E14smart("CS");
    public static final E14smart JAVA = new E14smart("JAVA");
    public static void main(String[] args) {
        E14smart lang = E14smart.JAVA;
        System.out.println(lang);
    }
}

Now:

public enum Language { C, CPP, CS, JAVA };
public class E15 {
    public static void main(String[] args) {
        Language lang = Language.JAVA;
        System.out.println(lang);
    }
}

A very useful feature in some cases.

I am sure it will be used, but it will take forever to get rid of integer constants.

Scanner class:

Java 1.5 got a utility class java.util.Scanner to parse input with.

Previous:

import java.io.*;

public class S14 {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Enter integer: ");
        int iv = Integer.parseInt(br.readLine());
        System.out.println(iv);
        System.out.print("Enter decimal number: ");
        double xv = Double.parseDouble(br.readLine());
        System.out.println(xv);
        System.out.print("Enter word: ");
        String sv = br.readLine();
        System.out.println(sv);
    }
}

Now:

import java.io.*;
import java.util.*;

public class S15 {
    public static void main(String[] args) throws Exception {
        Scanner scn = new Scanner(System.in);
        System.out.print("Enter integer: ");
        int iv = scn.nextInt();
        System.out.println(iv);
        System.out.print("Enter decimal number: ");
        double xv = scn.nextDouble();
        System.out.println(xv);
        System.out.print("Enter word: ");
        String sv = scn.next();
        System.out.println(sv);
    }
}

Useful feature in some cases.

UPDATE: It works great in these simple cases, but the semantics are so tricky in more complex cases, that I will not recommend using this class - too likely to encounter unexpected behavior.

I expect it to se some use.

Varargs:

Java 1.5 supports methods with variable number of arguments like C/C++ and C#.

Example:

public class VA {
    public static void doit(Object ... v) {
        for(int i = 0; i < v.length; i++) {
            System.out.print(" " + v[i]);
        }
        System.out.println();
    }
    public static void main(String[] args) {
        doit(1);
        doit(1, 2);
        doit(1, 2, 3);
    }
}

Practical feature in my opinion.

And I am sure it will see some use.

Formatted output:

Java 1.5 got formatted output via printf as known from C.

Example:

public class FIO {
    public static void main(String[] args) {
        int iv = 123;
        double xv = 123.456;
        String sv = "abc";
        System.out.printf("%d %f %s\n", iv, xv, sv);
    }
}

Nice feature but not so important.

UPDATE: 10 years later then I am really happy about this feature.

I expect that it will be used as everyone knows printf.

System.getenv:

Java 1.5 has reactivated System.getenv that got deactivated in 1.2.

Example:

public class GE {
    public static void main(String[] args) throws Exception {
        System.out.println(System.getenv("JAVA_HOME"));
    }
}

StringBuilder class:

Java 1.5 has supplemented/replaced StringBuffer class with a new StringBuilder class.

The StringBuilder-StringBuffer relationship is like HashMap-Hashtable and ArrayList-Vector.

The methods in StringBuilder are not synchronized and therefore sligthly more efficient. And even though synchronized methods prevent corruption of internal data structures, then it is rarely sufficient to make the entire code thread safe.

Anyway the rule is very simple: do use StringBuilder - do not use StringBuffer.

I don't think it is that important a change - the performance difference will rarely be signifiacnt.

I also suspect that it wil take 10 years to get rid of StringBuffer.

Concurrent utilities:

Java 1.5 got a new package java.util.concurrent with lots of classes to make it easier to write multi-threaded code.

Here is list of some of the most interesting parts:

I believe there is huge potential in this new package. It will make it so much easier and safer to write multi-threaded applications.

I expect peopel to start using it when they find out about it.

Annotations:

Java 1.5 has support for meta data in the code called annotations similar to C# attributes.

This feature is primarily targetting tools that generates dynamic proxies, AOP frameworks and similar.

But a few are also useful for ordinary code.

Example of the latter:

@Override
public void dosomething() {
   // whatever
}

This creates a compiler error if dosomething does not override a method in the super class.

This can be quite useful to avoid typo errors.

And I am sure that it will be used.

Class data sharing:

Java 1.5 maps readonly data in classes to shared memory to use less memory when running multiple JVM's on the same system.

JMX:

Java 1.5 comes with a framework for management called JMX.

Next:

See Java 1.6/6 New Features.

Article history:

Version Date Description
1.0 February 11th 2004 Initial version (in Danish) published on Eksperten.dk
1.2 October 29th 2004 Several changes after release
1.3 November 5th 2004 Add Scanner and System.getenv
1.4 August 5th 2005 Add StringBuilder and thread pool
2.0 August 6th 2016 Translation to English and complete reformatting and publishing here
2.1 October 8th 2016 Add content overview
2.2 March 23rd 2017 Add release dates

Other articles:

See list of all articles here

Comments:

Please send comments to Arne Vajhøj