Translate the content to your language. Select your Language below.

Tuesday, September 24, 2013

New Features of Java 7.0

Java 7.0 Features 

switch on String

Before JDK 7, only integral types can be used as selector for switch-case statement. In JDK 7, you can use a String object as the selector. For example,
String day = "SAT";
switch (day) {
   case "MON": System.out.println("Monday"); break;
   case "TUE": System.out.println("Tuesday"); break;
   case "WED": System.out.println("Wednesday"); break;
   case "THU": System.out.println("Thursday"); break;
   case "FRI": System.out.println("Friday"); break;
   case "SAT": System.out.println("Saturday"); break;
   case "SUN": System.out.println("Sunday"); break;
   default: System.out.println("Invalid");
}
String.equals() method is used in comparison, which is case-sensitive. Java compiler can generate more efficient code than using nested if-then-else statement.
This feature is handy in handling options specified in command-line arguments, which are Strings. For example (slightly neater code than using nested if-then-else statement),
// This program accepts three command-line options
//   -c : create
//   -v : verbose
//   -d : debug
// More than one options can be specified in any order.
public class SwitchOnString {
   public static void main(String[] args) {
      boolean create = false;
      boolean verbose = false;
      boolean debug = false;
 
      for (String arg: args) {
         switch (arg) {
            case "-c": create = true; break;
            case "-v": verbose = true; break;
            case "-d": debug = true; break;
            default:
               System.out.println("invalid option");
               System.exit(1);
         }
      }
 
      System.out.println("create: " + create);
      System.out.println("verbose: " + verbose);
      System.out.println("debug: " + debug);
   }
}

Binary Literals with prefix "0b"

In JDK 7, you can express literal values in binary with prefix '0b' (or '0B') for integral types (byteshortint and long), similar to C/C++ language. Before JDK 7, you can only use octal values (with prefix '0') or hexadecimal values (with prefix '0x' or '0X').
You are also permitted to use underscore (_) to break the digits to improve the readability but you must start and end with a digit, e.g.,
int number1 = 0b01010000101000101101000010100010;
int number2 = 0b0101_0000_1010_0010_1101_0000_1010_0010;
int number3 = 2_123_456;  // break the digits with underscore
For example,
public class BinaryLiteralTest {
   public static void main(String[] args) {
      // Some 32-bit 'int' literal values
      int anInt1 = 0b0101_0000_1010_0010_1101_0000_1010_0010;
      int anInt2 = 0b0011_1000;
 
      // An 8-bit 'byte' literal value. By default, literal values are 'int'.
      // Need to cast to 'byte'
      byte aByte = (byte)0b0110_1101;
 
      // A 16-bit 'short' literal value
      short aShort = (short)0b0111_0101_0000_0101;
 
      // A 64-bit 'long' literal value. Long literals requires suffix "L".
      long aLong = 0b1000_0101_0001_0110_1000_0101_0000_1010_0010_1101_0100_0101_1010_0001_0100_0101L;
 
      // Formatted output: "%d" for integer in decimal, "%x" in hexadecimal, "%o" in octal.
      // Take note that "%b" prints true or false (for null), NOT binary.
      System.out.printf("%d(%x)(%o)(%b)\n", anInt1, anInt1, anInt1, anInt1);
      System.out.printf("%d(%x)(%o)(%b)\n", aByte, aByte, aByte, aByte);
   }
}
1352847522(50a2d0a2)(12050550242)(true)
109(6d)(155)(true)

Underscore for Numeric Literals

In JDK 7, you could insert underscore(s) '_' in between the digits in an numeric literals (integral and floating-point literals) to improve readability. For example,
int anInt = 0b10101000_01010001_01101000_01010001;
double aDouble = 3.1415_9265;
float  aFloat = 3.14_15_92_65f;

Catching Multiple Exception Types

In JDK 7, a single catch block can handle more than one exception types.
For example, before JDK 7, you need two catch blocks to catch two exception types although both perform identical task:
try {
   ......
} catch(ClassNotFoundException ex) {
   ex.printStackTrace();
} catch(SQLException ex) {
   ex.printStackTrace();
}
In JDK 7, you could use one single catch block, with exception types separated by '|'.
try {
   ......
} catch(ClassNotFoundException|SQLException ex) {
   ex.printStackTrace();
}
[TODO] A complete example on file IO.

The try-with-resources Statement

For example, before JDK 7, we need to use a finally block, to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly. The code is messy!
import java.io.*;
// Copy from one file to another file character by character.
// Pre-JDK 7 requires you to close the resources using a finally block.
public class FileCopyPreJDK7 {
   public static void main(String[] args) {
      BufferedReader in = null;
      BufferedWriter out = null;
      try {
         in  = new BufferedReader(new FileReader("in.txt"));
         out = new BufferedWriter(new FileWriter("out.txt"));
         int charRead;
         while ((charRead = in.read()) != -1) {
            System.out.printf("%c ", (char)charRead);
            out.write(charRead);
         }
      } catch (IOException ex) {
         ex.printStackTrace();
      } finally {            // always close the streams
         try {
            if (in != null) in.close();
            if (out != null) out.close();
         } catch (IOException ex) {
            ex.printStackTrace();
         }
      }
 
      try {
         in.read();   // Trigger IOException: Stream closed
      } catch (IOException ex) {
         ex.printStackTrace();
      }
   }
}
JDK 7 introduces a try-with-resources statement, which ensures that each of the resources in try(resourses) is closed at the end of the statement. This results in cleaner codes.
import java.io.*;
// Copy from one file to another file character by character.
// JDK 7 has a try-with-resources statement, which ensures that
// each resource opened in try() is closed at the end of the statement.
public class FileCopyJDK7 {
   public static void main(String[] args) {
      try (BufferedReader in  = new BufferedReader(new FileReader("in.txt"));
           BufferedWriter out = new BufferedWriter(new FileWriter("out.txt"))) {
         int charRead;
         while ((charRead = in.read()) != -1) {
            System.out.printf("%c ", (char)charRead);
            out.write(charRead);
         }
      } catch (IOException ex) {
         ex.printStackTrace();
      }
   }
}

Type Inference for Generic Instance Creation

import java.util.*;
public class JDK7GenericTest {
   public static void main(String[] args) {
      // Pre-JDK 7
      List lst1 = new ArrayList();
      // JDK 7 supports limited type inference for generic instance creation
      List lst2 = new ArrayList<>();
 
      lst1.add("Mon");
      lst1.add("Tue");
      lst2.add("Wed");
      lst2.add("Thu");
 
      for (String item: lst1) {
         System.out.println(item);
      }
 
      for (String item: lst2) {
         System.out.println(item);
      }
   }
}

Note:- I read this in http://www.ntu.edu.sg and posted the content for (y)our reference.


No comments:

Post a Comment