Tuesday, October 16, 2012

Java Coding Tips with New Features

Every release of JDK involves few minor enhancements, which are majorly overlooked under the shadow of major ones, but can be very handy in day-to-day coding. In this article I tried to collate a list of such minor enhancements (taken from JDK 5, 6 and 7), which can really make your code efficient, clean and less error-prone.

Catching Multiple Exceptions in Single Catch Block (Since JDK 7)

Consider  an example where your try block can throw multiple exceptions and those are caught separately but the codes within catch blocks are same, as shown below
 
try {
    //some code which can throw IOException and ParseException
            } catch (ParseException exception) {
             //log the error
            //create new custom exception
            //throw exception
} catch (IOException exception) {
           //log the error
           //create new custom exception
           //throw custom exception
            }
 
The multiple catch blocks can be combined together as shown below
try {
//some code which can throw IOException and ParseException
            } catch (ParseException | IOException exception) {
                 //log the error
                //create new custom exception
                //throw custom exception
            }
 
This can improve the code reusability, exception handling and overall code structure.

Try with Resources (Since JDK 7)

How many times you needed to take care of closing the streams and other resources after performing write/read operations. Typically we use finally blocks for these mandatory actions. But now the same can be auto-close by Java, if you use try-with-resource blocks as shown below.
Older way:
            FileInputStream fis = null;
       try {
              fis = new FileInputStream("SomeFile")
              //Do something with File input stream, but you needn't to close it.
             } catch (IOException ioException) {
              //Do something      
       } finally {
              fis.close();
       }
 
Try with resource statement:
           try (FileInputStream fis = new FileInputStream("SomeFile")) {
              //Do something with File input stream, but you needn't to close it.
           } catch (IOException ioException) {
              //Do something
           }
 
 
This will allow developers to avoid error of not closing the resource and extra repeating code. Any implementation of AutoCloseable interface can be used as resource with try block.

Switch with String (Since JDK 7)

A much awaited feature of Java. Prior to 7, only int or enums were allowed inside switch statement, but with jdk 7, you can also work with Strings inside switch, as shown below:
 
           String day = "Tuesday";
           switch (day) {
              case "Monday" : //do something
              break;         
              case "Tuesday" : //do something
              break;            
              default : //for all other days
              break;
           }

Underscore in Numeric Literals (Since JDK 7)

Many times, while using numerical literals, you found it difficult to read its value for e.g.
 
long bankAccountNumber = 1007876345678L;
How good it would be, if we can use some separator for better readability (for e.g. if first 3 digits indicates bank’s state wise code, while next 4 for bank code and rest as individual number)? JDK 7 allows you to use as many underscores as you need within the numeric literals. For e.g.
 
long bankAccountNumber = 100_7876_345678L;
This greatly improves the readability of your code.

Type Inference for Generic Instance Creation (Since JDK 7)

Prior to Java 7, if you use generics, you need to pass type arguments to call appropriate constructor, but with JDK 7 now that is options hence the code,
 
Map> mapofMap = new HashMap>(); 
Can now be replaced with
Map> mapofMap = new HashMap<>();
This enhances the code readability, and avoid unnecessary repetition of generic parameters.

Varargs (Since JDK 5)

How many times you need to create an array, may be of single value, just because your method needs array as input? Let’s see the code below

public class Test { 
       public static void main(String[] args) {
              String inputsingle = "SingleString";
              new Test().needArray(new String[]{inputsingle});
       }
       private void needArray(String[] input) {
              //do something with string array
       }
}
But now with JDK 5, the last parameter of the method can have 3 dots to represent varargs, which means, the compiler will create the array while invoking this method for you. Hence the above code can be written as shown below:
public class Test { 
       public static void main(String[] args) {
              String inputsingle = "SingleString";
              new Test().needArray(inputsingle);
              new Test().needArray(new String[]{"a", "b","c"});     
       }
       private void needArray(String...input) {
              //do something with string array
       }
}  

Static Imports (Since JDK 5)

If you fade up using class name for static variables, you can use static import as shown below.
Instead of writing code like
       Color black = Color.BLACK;
       Color red = Color.RED;
You would write like
import static java.awt.Color.*;
and then use the static variable directly
Color black = BLACK;
       Color red = RED;
This avoids the repeating prefixing of class name. But beware, it can reduce the code readability as well. Read More: http://docs.oracle.com/javase/1.5.0/docs/guide/language/static-import.html

Rethrowing exceptions with improved types (Since JDK 7)

There are instances where, although you catch the higher level exception but still, you want to throw specific exceptions. Let’s consider the code below which is valid for JDK 6 and prior versions:

public void method() throws Exception {
              try {
         //Some code which can throw Exception1 and Exception 2 (sublcasses of Exception)
             } catch (Exception e) {
                     throw e;
             }
       }
With the improved types in throws clause in JDK 7, now you can also throw specific exceptions, thus the above method can also be written as
public void method() throws Exception1, Exception2 {
              try {
         //Some code which can throw Exception1 and Exception 2 (sublcasses of Exception)
              } catch (Exception e) {
                     throw e;
              }
       }
As complier can understand that the code can only throw Exception1 and Exception2, it allows to define method which can throw specific exception, along with allowing the catch of higher level exception object.
 
 

No comments: