Modernize old code

Java has been around since 1995. There is a large amount of code that has been written for older versions of the JDK. Such code will still run, but there are many advantages to modernizing such code, when you get the chance, to take advantage of more modern libraries and language features.

In particular, the Java 5 release (JDK 1.5) marked a significant change, and noticeably altered (and improved) the character of typical Java code. When updating old code to more recent versions of Java, it's helpful to use a quick checklist of things to look out for. Here's a list of such items related to the Java 5 release:

Use @Override liberally
The @Override standard annotation identifies methods that override a superclass method. It should be used liberally to indicate your intent to override. It's also used when implementing methods defined by an interface.

Avoid raw types
Raw types should almost always be avoided in favor of parameterized types.

Use for-each loops
The enhanced for loop (also called the for-each loop) should be used whenever available. It's more compact, concise, and clear.

Replace constants with enumerations
Using public static final constants to represent sets of related items should be avoided in favor of the enumerations now supported by Java. In addition, you should consider replacing any "roll-your-own" implementations of type-safe enumerations with the new language construct.

Replace StringBuffer with StringBuilder
The older StringBuffer class is thread-safe, while the new StringBuilder is not. However, it's almost always used in a context in which thread safety is superfluous. Hence, the extra cost of synchronization is paid without benefit. Although the performance improvement in moving from StringBuffer to StringBuilder may only be very slight (or perhaps not even measurable), it's generally considered better form to prefer StringBuilder.

Use sequence parameters when appropriate
Sequence parameters (varargs) let you replace Object[] parameters (containing 0..N items) appearing at the end of a parameter list with an alternate form more convenient for the caller. For example,

  public static void main(String[] aArgs){}
can now be replaced with:
  public static void main(String... aArgs){}

Be careful with Comparable
The Comparable interface has been made generic. For example,

  class Anatomy implements Comparable{
    public int compareTo(Object aThat){}
  }
should now be replaced with :
  class Anatomy implements Comparable<Anatomy>{
    public int compareTo(Anatomy aThat){}
  }

In addition, JDK 7 also has some new tools which improve the character of typical Java code:

Use 'diamond' syntax for generic declarations
Declarations of the form:

  List<String> blah = new ArrayList<String>();
  Map<String, String> blah = new LinkedHashMap<String, String>();
can now be replaced with a more concise syntax:
  List<String> blah = new ArrayList<>();
  Map<String, String> blah = new LinkedHashMap<>();

Use try-with-resources
The try-with-resources feature lets you eliminate most finally blocks in your code.

Use Path and Files for basic input/output
The new java.nio package is a large improvement over the older File API.

Example

Here's an example of code written using Java 5 features:


import java.util.*;

public final class Office {

  /** 
  * Use sequence parameter (varargs) for main method.
  * 
  * Use a sequence parameter whenever array parameter appears at 
  * the END of the parameter list, and represents 0..N items.
  */
  public static void main(String... aArgs){
    //Use parameterized type 'List<String>', not the raw type 'List'
    List<String> employees = Arrays.asList("Tom", "Fiorella", "Pedro");
    Office office = new Office(AirConditioning.OFF, employees);    
    System.out.println(office);
    
    //prefer the for-each style of loop
    for(String workingStiff: employees){
      System.out.println(workingStiff);
    }
  }

  /**
  * Preferred : use enumerations, not int or String constants.
  */
  enum AirConditioning {OFF, LOW, MEDIUM, HIGH}

  /*
  * Definitely NOT the preferred style :
  */
  public static final int OFF = 1;
  public static final int LOW = 2;
  public static final int MEDIUM = 3;
  public static final int HIGH = 4;
  
  Office(AirConditioning aAirConditioning, List<String> aEmployees){
    fAirConditioning = aAirConditioning;
    fEmployees = aEmployees; //(no defensive copy here)
  }
  
  AirConditioning getAirConditioning(){
    return fAirConditioning;
  }
  
  List<String> getEmployees(){
    return fEmployees; 
  }

  /*
  * Get used to typing @Override for toString, equals, and hashCode :
  */
  
  @Override public String toString(){
    //..elided
  }
  
  @Override public boolean equals(Object aThat){
    //..elided
  }
  
  @Override public int hashCode(){
    //..elided
  }
  
  // PRIVATE //
  private final List<String> fEmployees;
  private final AirConditioning fAirConditioning;
} 



See Also :
Type-Safe Enumerations
Implementing compareTo
Know the core libraries
Overloading can be tricky
Use for-each liberally
Use @Override liberally
Avoid raw types
Prefer modern libraries for concurrency
Would you use this technique?
Yes   No   Undecided   
© 2014 Hirondelle Systems | Source Code | Contact | License | RSS
Individual code snippets can be used under this BSD license - Last updated on September 21, 2013.
Over 2,000,000 unique IPs last year - Built with WEB4J.
- In Memoriam : Bill Dirani -