I am about to start my first professional career position as a software developer, and I'm likely going to be writing a lot of Java code. I don't know that much about what specifically I'll be writing, and besides, I have fairly broad interests when it comes to code anyway.

For reasons not worth discussing, my last internship had me coding only for the Java 1.3 and 1.4 SDK's. Also, my university education has focused mainly on algorithms, data structures, and other theory, not language features or libraries.

So, with the above in mind, what features, classes, etc. in the current version of Java (what number are we on now, anyway?) would be worth my time to read up on and why? What have I missed since 1.4.2 that makes your life as a programmer easier?

Examples and stories of how you discovered a particular package or some such and put it to use would also be great.

  • 4
    What are these reasons that are not worth discussing? Many of us are intrigued...
    – immutabl
    Dec 6, 2010 at 15:17
  • @5arx Well I worked with a 1.4 version of java for Robotics Programming because for some reason that was what our platform supported. Jun 1, 2012 at 20:57

10 Answers 10


The changes that I consider most important are:

  • Generics (e.g. typed collections, like Set)

  • Enhanced for loop (for (String s : set) {...})

  • Autoboxing/unboxing (automatically convert between types like Integer to int and vice versa)

  • Typesafe enums (enum is now a keyword, types can be created out of enums)

  • Varargs (for printf() function, allows variable number of arguments)

  • Static import (can now import static methods of a class, such as java.lang.Math)

  • Annotations

  • java.util.concurrent (Demonstrates java's concurrency)

Also read What Java are you aiming for?, to get a better understanding of each of the three versions.

  • 1
    ++ the enhanced for loop, autoboxing/unboxing, varargs, static import are simple Dec 6, 2010 at 13:31
  • Why do Java programmers call for-each loops "enhanced for loops?"
    – Maxpm
    Feb 28, 2012 at 21:13
  • 2
    @Maxpm Because that's how it's called in Java Language Specification. As per JLS, there are basic for loops and enhanced for loops. I'm not sure why they decided to do it that way. Maybe because the syntax doesn't use a special keyword and sort of blends in with the normal loops.
    – Malcolm
    Feb 28, 2012 at 22:10

The single most important change in your day to day programming life is the introduction of generics which will most likely be used in every new module you will be asked to write, and it is a confusing new syntax.

Generics is the mechanism allowing e.g. a List to contain strings instead of naked objects, where the compiler enforces that an item to be put into the the list is a String, and it knows that when you get an item out of a list it is a String.

This makes for better programs as you avoid the explicit runtime cast to the target type (which is a frequent source of errors if you get it wrong) and the IDE can help you doing all the dirty work as it knows much more about your code than it did when it was just list of objects.

Joshua Bloch has written a good introduction to Generics, which is available as the sample chapter at http://java.sun.com/docs/books/effective/

  • Please do NOT tell the Groovy people! "This makes for better programs as you avoid the runtime cast to the target type." def whatever.... Dec 6, 2010 at 14:32
  • @Yar, edited to be more explicit. I would LOVE the "def" or "var" attribute. Would make my life a bit easier.
    – user1249
    Dec 6, 2010 at 14:54
  • Yes, I was just thinking this recently with Objective-C and the id which is def or var.... but then again, the safety of 100% static typing is amazing, really. Dec 7, 2010 at 5:15
  • @Yar : You'll love Ada :)
    – mattnz
    Feb 28, 2012 at 23:31
  • @mattnz why, particularly? And while we're here, does it run on the JVM? Feb 29, 2012 at 15:32

Autoboxing is a nice feature introduced with Java 5. Just like in C# the compiler now makes an automatic conversion between the primitive (basic) types and their corresponding object wrapper classes (int to Integer etc) and back again. That makes working with Java Collections much less pain.

For-each looping was new in Java 5, too, I think. It makes iterating over arrays (and collections) easier, because it eliminates much of the usual clutter involving the setup and management of an index variable or iterators. At example:

void myMethod(Collection<myObjectType> c) {
    for (myObjectType o : c)

Enums, to replace final statics and constants and help you remove references to strings and magic numbers. An example taken from the good people at sun/oracle :

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7),
    PLUTO   (1.27e+22,  1.137e6);

    private final double mass;   // in kilograms
    private final double radius; // in meters
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    public double mass()   { return mass; }
    public double radius() { return radius; }

    // universal gravitational constant  (m3 kg-1 s-2)
    public static final double G = 6.67300E-11;

    public double surfaceGravity() {
        return G * mass / (radius * radius);
    public double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();


public static void main(String[] args) {
        double earthWeight = Double.parseDouble(args[0]);
        double mass = earthWeight/EARTH.surfaceGravity();
        for (Planet p : Planet.values())
           System.out.printf("Your weight on %s is %f%n",
                             p, p.surfaceWeight(mass));

java.util.concurrent was introduced in 1.5. The best resource for learning it is (probably) the Java Concurrency in Practice book. IMHO concurrency is Java's most important competitive advantage compared to anything else so it's definitely worth knowing well.

  • 1
    +1 For mentioning the concurrent package.It's sad that so many developers still use concurrency primitives like Threads, wait()/notify() and synchronize, ... Dec 6, 2010 at 11:46
  • Indeed. java.util.concurrent to concurrency primitives is like automatic memory management to manual memory management. Using the latter is just a recipe to spending more of your time on debugging and offers no advantages. Dec 6, 2010 at 14:20
  • Executors to the rescue! Even better in Java 6
    – user1249
    Dec 6, 2010 at 14:32
  • +1000 if I could - that book is amazing
    – Gary
    Dec 6, 2010 at 17:56

Well, StringBuilder helped me to speed up my program. It is an equivalent of the StringBuffer without thread safety.

  • Yep. Effective Java states that StringBuffer is obsolete and should be replaced by StringBuilder.
    – Gary
    Dec 6, 2010 at 17:54
  • 1
    Concatenation with + of strings automatically use StringBuilder instead of StringBuffer for source level 1.5 and higher.
    – user1249
    Feb 8, 2011 at 7:33

I'll help by categorising the helpful answer from @ykombinator. His list is a list of the elements that you will use on a daily basis while doing "general" java development.

Low impact and low difficulty:

  • Enhanced for loop (for (String s : set) {...})
  • Autoboxing/unboxing (automatically convert between types like Integer to int and vice versa)
  • Varargs (for printf() function, allows variable number of arguments)
  • Static import (can now import static methods of a class, such as java.lang.Math)

High Impact and medium difficulty:

  • Typesafe enums (enum is now a keyword, types can be created out of enums)

High Impact and high difficulty:

  • Annotations
  • Generics

Low impact and high difficult (will only use unless you do advanced threading)

  • java.util.concurrent (Demonstrates java's concurrency)

I would suggest therefore that you read through the docs/help on low impact low difficult pieces - they're easy to pick up. Spend a lo tof time on Annotations and Generics - annotations are very useful, and generics can get rather complicated.

Only look at the new concurrency content if you need to do threading.


Since I can't comment because I'm below 50 I'll leave an answer. It's been already mentioned but I'll repeat it again: Annotations! This kind of metadata became the most important thing in my years of Java experience. It well used like some frameworks do it makes the code much more concise and clean. For example, annotations can:

  • Convert an object into an entity @Entity
  • Convert a method into a REST service @GET
  • Explain that a method will never return null @nonnull
  • Set an object to a field for dependency injection @inject

And of course you can build your own annotations and know if a method, class or field is annotated using reflection.

  • 2
    To be precise annotations cannot do these things, as they just put meta-information in the code, which other code - frequently a special classloader - can take action on. I consider annotations to be a very good general solution to a lot of problems.
    – user1249
    Feb 8, 2011 at 7:32

Learning by example works for me

Here is a quick example of idiomatic Java 6

public class Main {
  public static void main(String[] args) {
    // Shows a list forced to be Strings only
    // The Arrays helper uses generics to identify the return type
    // and takes varargs (...) to allow arbitary number of arguments
    List<String> genericisedList = Arrays.asList("A","B","C");

    // Demonstrates a for:each loop (read as for each item in genericisedList)
    for (String item: genericisedList) {
      System.out.printf("Using print formatting: %s%n",item);

    // Note that the object is initialised directly with a primitive (autoboxing)
    Integer autoboxedInteger = 1;


Don't bother with Java5, it's deprecated in respect to Java6.

Next step, annotations. These just define aspects to your code that allow annotation readers to fill in boilerplate configuration for you. Consider a simple web service that uses the JAX-RS specification (it understands RESTful URIs). You don't want to bother doing all the nasty WSDL and mucking about with Axis2 etc, you want a quick result. Right, do this:

// Response to URIs that start with /Service (after the application context name)
public class WebService {

  // Respond to GET requests within the /Service selection
  // Specify a path matcher that takes anything and assigns it to rawPathParams
  public Response service(@Context HttpServletRequest request, @PathParam("rawPathParams") String rawPathParams) {
    // Do some stuff with the raw path parameters 

    // Return a 200_OK
    return Response.status(200).build();

Bang. With a little sprinkle of configuration magic in your web.xml you're off. If you're building with Maven and have the Jetty plugin configured, your project will have it's own little web server right out of the box (no fiddling about with JBoss or Tomcat for you), and the above code will respond to URIs of the form:

GET http://localhost:8080/contextName/Service/the/raw/path/params

Job done.


Wow that was a blast from the past! I've not used Java for 4 years now - and nothing has changed at all in that time!

There's a list of features by version, but here's the important bit (plagiarised of course)...

J2SE 5.0 (September 30, 2004)

  • Generics: Provides compile-time (static) type safety for collections and eliminates the need for most typecasts (type conversion).
  • Metadata: Also called annotations; allows language constructs such as classes and methods to be tagged with additional data, which can then be processed by metadata-aware utilities.
  • Autoboxing/unboxing: Automatic conversions between primitive types (such as int) and primitive wrapper classes (such as Integer).
  • Enumerations: The enum keyword creates a typesafe, ordered list of values (such as Day.MONDAY, Day.TUESDAY, etc.). Previously this could only be achieved by non-typesafe constant integers or manually constructed classes (typesafe enum pattern).
  • Swing: New skinnable look and feel, called synth.
  • Varargs: The last parameter of a method can now be declared using a type name followed by three dots (e.g. void drawtext(String... lines)). In the calling code any number of parameters of that type can be used and they are then placed in an array to be passed to the method, or alternatively the calling code can pass an array of that type.
  • Enhanced for each loop: The for loop syntax is extended with special syntax for iterating over each member of either an array or any Iterable, such as the standard Collection classes, using a construct of the form:

Java SE 6 (December 11, 2006)

  • Support for older Win9x versions dropped. Unofficially Java 6 Update 7 is the last release of Java shown to work on these versions of Windows. This is believed to be due to the major changes in Update 10.
  • Scripting Language Support: Generic API for tight integration with scripting languages, and built-in Mozilla JavaScript Rhino integration
  • Dramatic performance improvements for the core platform, and Swing.
  • Improved Web Service support through JAX-WS
  • JDBC 4.0 support.
  • Java Compiler API an API allowing a Java program to select and invoke a Java Compiler programmatically.
  • Upgrade of JAXB to version 2.0: Including integration of a StAX parser.
  • Support for pluggable annotations
  • Many GUI improvements, such as integration of SwingWorker in the API, table sorting and filtering, and true Swing double-buffering (eliminating the gray-area effect).
  • JVM improvements include: synchronization and compiler performance optimizations, new algorithms and upgrades to existing garbage collection algorithms, and application start-up performance.

That's about it. Java SE 7.0 looks more interesting but isn't released yet.

Considering how many new language features and APIs have been added to C# in the last 4 years, I'm quite astonished. What's been going on at Sun/Oracle?

  • Sun decided to open source Java. This is the thing that has ensured that regardless what Oracle decides to do we can still run OpenJDK on Linux boxes. That only delayed them 18-24 months...
    – user1249
    Dec 6, 2010 at 14:33
  • @Thorbjørn - that might explain it. It's a shame how much disruption this acquisition has caused. I guess C# enjoys comparative stability: we've had lambdas since 2006 - where as they look like they'll not get into Java until 2012 now. Dec 6, 2010 at 23:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.