New Features in Java 7


Bhaskar S 04/06/2014


Overview

Java 7 was released around the mid of 2011 and has some new language features that may be have been overlooked by Java developers.

In this article, we will explore some of those capabilities through code samples.

So without further ado, lets get started !!!

Java 7 :: New Features

Binary Literals

Integral types byte, short, int, and long can also be expressed using the binary number system (0s and 1s). To specify a binary value, prefix the value with a 0b or 0B.

The following is the example that demonstrates the use of binary literals:

Listing.1
/*
 * 
 * Name:   Sample01
 * 
 * Author: Bhaskar S
 * 
 * Date:   03/29/2014
 * 
 */

package com.polarsparc.java7;

public class Sample01 {
    public static void main(String[] args) {
        // Binary Literals
        byte a = (byte) 0b10101010;
        short b = (short) 0b11110000;
        int c = (int) 0B10011001;
        long d = 0b101110111011;
        System.out.printf("a [%s] = %d, b [%s] = %d, c [%s] = %d, d [%s] = %d\n", Integer.toBinaryString(a), a,
            Integer.toBinaryString(b), b, Integer.toBinaryString(c), c, Long.toBinaryString(d), d);
    }
}

Executing the program will generate the following output:

Output.1

a [11111111111111111111111110101010] = -86, b [11110000] = 240, c [10011001] = 153, d [101110111011] = 3003

Underscore Literals

To improve readability of numeric literals in the code, one can use underscores between digits to separate a group of digits.

The following is the example that demonstrates the use of underscore literals:

Listing.2
/*
 * 
 * Name:   Sample02
 * 
 * Author: Bhaskar S
 * 
 * Date:   03/29/2014
 * 
 */

package com.polarsparc.java7;

public class Sample02 {
    public static void main(String[] args) {
        // Underscore Literals
        byte a = (byte) 0b1010_0101;
        short b = (short) 1_234;
        int c = 12_345;
        long d = 123_456L;
        float e =     1.23_45F;
        System.out.printf("a = %d, b = %d, c = %d, d = %d, e = %g\n", a, b, c, d, e);
    }
}

Executing the program will generate the following output:

Output.2

a = -91, b = 1234, c = 12345, d = 123456, e = 1.23450

Diamond Operator

One can minimize extra typing of the type arguments (that was required in the earlier versions of Java) to invoke the constructor of a generic class with an empty type parameter <>. The Java the compiler will infer the type arguments from the context.

The following is the example that demonstrates the use of the diamond operator:

Listing.3
/*
 * 
 * Name:   Sample03
 * 
 * Author: Bhaskar S
 * 
 * Date:   03/29/2014
 * 
 */

package com.polarsparc.java7;

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

public class Sample03 {
    public static void main(String[] args) {
        // Diamond operator <>
        List<String> list = new ArrayList<>();
        list.addAll(Arrays.asList("One", "Two", "Three"));
        System.out.printf("list = %s\n", list);
    }
}

Executing the program will generate the following output:

Output.3

list = [One, Two, Three]

Strings with Switch

The switch statement now supports the use of Java String object in its expression. The switch statement compares the String object from its expression with each of the case values using the String.equals() method which is case sensitive.

The following is the example that demonstrates the use of Java String in the switch statement:

Listing.4
/*
 * 
 * Name:   Sample04
 * 
 * Author: Bhaskar S
 * 
 * Date:   03/29/2014
 * 
 */

package com.polarsparc.java7;

public class Sample04 {
    public static void main(String[] args) {
        final String ONE = "one";
        final String TWO = "two";
        final String SIX = "six";
        
        String s = "two";
        
        // Enhanced Switch
        switch (s) {
            case ONE:
                System.out.printf("ONE\n");
                break;
            case TWO:
                System.out.printf("TWO\n");
                break;
            case SIX:
                System.out.printf("SIX\n");
                break;
            default:
                System.out.printf("*NONE*\n");
                break;
        }
    }
}

Executing the program will generate the following output:

Output.4

TWO      

Try with Resources

In the earlier versions of Java, if we had to work with file, network or database resources, we would open the resource within the try block, handle any exceptions in the catch block and close the resource in the finally block.

The following is the example that demonstrates the opening and reading a file:

Listing.5
/*
 * 
 * Name:   Sample05
 * 
 * Author: Bhaskar S
 * 
 * Date:   03/29/2014
 * 
 */

package com.polarsparc.java7;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Sample05 {
    public static void main(String[] args) {
        final String FILE = "./data/file.dat";
        
        BufferedReader br = null;
        
        try {
            String ln;
            br = new BufferedReader(new FileReader(FILE));
            while ((ln = br.readLine()) != null) {
                System.out.printf("->Line: %s<-\n", ln);
            }
        }
        catch (IOException ex) {
            ex.printStackTrace(System.err);
        }
        finally {
            if (br != null) {
                try {
                    br.close();
                }
                catch (Exception e) {
                    e.printStackTrace(System.err);
                }
            }
        }
    }
}

Executing the program will generate the following output:

Output.5

->Line: Hello<-
->Line: Welcome<-
->Line: to<-
->Line: Java 7<-    

With the try-with-resources statement, the try statement declares one or more resource(s). The try-with-resources statement ensures that each of the resource(s) is closed at the end of the statement.

The following is the example that demonstrates the opening and reading a file using the try-with-resources statement, resulting in elegant code:

Listing.6
/*
 * 
 * Name:   Sample06
 * 
 * Author: Bhaskar S
 * 
 * Date:   03/29/2014
 * 
 */

package com.polarsparc.java7;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Sample06 {
    public static void main(String[] args) {
        final String FILE = "./data/file.dat";
        
        // try-with-resources
        try (BufferedReader br = new BufferedReader(new FileReader(FILE))) {
            String ln;
            while ((ln = br.readLine()) != null) {
                System.out.printf("->Line: %s<-\n", ln);
            }
        }
        catch (IOException ex) {
            ex.printStackTrace(System.err);
        }
    }
}

Executing the program will generate the same result as in Output.5 above.

Catching Multiple Exception Types

In the earlier versions of Java, we would have multiple catch blocks to handle the different types of exceptions emitted from the try block.

The following is the example that demonstrates the handling of multiple exception types:

Listing.7
/*
 * 
 * Name:   Sample07
 * 
 * Author: Bhaskar S
 * 
 * Date:   03/29/2014
 * 
 */

package com.polarsparc.java7;

public class Sample07 {
    public static void main(String[] args) {
        try {
            String s[] = { "123", "345" };
            System.out.printf("->String: %s<-\n", s[0]);
            int n = Integer.parseInt(s[1]);
            System.out.printf("->Number: %d<-\n", n);
        }
        catch (ArrayIndexOutOfBoundsException ex) {
            ex.printStackTrace(System.err);
        }
        catch (NumberFormatException ex) {
            ex.printStackTrace(System.err);
        }
    }
}

Executing the program will generate the following output:

Output.6

->String: 123<-
->Number: 345<-

In Java 7, a single catch statement can handle the different exception types.

The following is the example that demonstrates a single catch statement handling different exception types, resulting in elegant code:

Listing.8
/*
 * 
 * Name:   Sample08
 * 
 * Author: Bhaskar S
 * 
 * Date:   03/29/2014
 * 
 */

package com.polarsparc.java7;

public class Sample08 {
    public static void main(String[] args) {
        // Catching Multiple Exception Types
        try {
            String s[] = { "123", "345" };
            System.out.printf("->String: %s<-\n", s[0]);
            int n = Integer.parseInt(s[1]);
            System.out.printf("->Number: %d<-\n", n);
        }
        catch (ArrayIndexOutOfBoundsException | NumberFormatException ex) {
            ex.printStackTrace(System.err);
        }
    }
}

Executing the program will generate the same result as in Output.6 above.