Java 7 features

OH my goodness, java 8 just was released but you are posting about java 7 features? Sure it has been some time but many developers don't get the luxury within corporate walls to use all the new goodies since most environments are dependent on third party updates. When a third party announces support of a new version of the JDK typically it isn't available for download and production ready like your typical open source package. Internally there is planning, migration of applications, environment set up, testing and a crap load of meetings that occur before use. So while new versions become mainstream it takes years for most version to gain penetration.

There are a lot of good articles on java 7 features but I will use this post to summarize just a few points that I feel are most relevant to a java enterprise developer. Once the upgrade does occur, one should understand all of the environments that your company has in house. So lets say you have environment A that is dependent on JDK 1.6 and doesn't have an upgrade path. If you start developing JDK 1.7 features, you won't be able to deploy to environment B that supports JDK 1.7 which is something to be aware of and have a discussion around.

Switch statement now supports strings

While I am not a huge fan of the switch statement you can now use a String object in the switch statement's expression.

BeforeUsing 1.7
@Test
public void using_string_switch_statement_old() {

    String val = "hello";

    if (val.equals("hello")) {
        System.out.println("hello");
    } else if (val.equals("world")) {
        System.out.println("world");
    }
}
@Test
public void using_string_switch_statement() {

    String val = "hello";

    switch (val) {
    case "hello":
        System.out.println("hello");
        break;
    case "world":
        System.out.println("world");
        break;

    default:
        break;
    }
}

Diamond operator

In java 7 you can use the diamond operator to reduce verbosity by having the compiler infer parameter types for constructors of generic classes. Even though this shortcut exists, I am still a huge fan of guava's collection utilities way to initialize an arraylist with values or just initialize a map.

BeforeUsing 1.7
@Test
public void diamond_operator_old() {

    Map<String, Object> map = new HashMap<String, Object>();

    List<String> myStrings = new ArrayList<String>();

    // guava
    List<String> myStrings2 = Lists.newArrayList("", "");
}    
@Test
public void diamond_operator() {

    Map<String, Object> map = new HashMap<>();

    List<String> myStrings = new ArrayList<>();
}            

Automatic resource management

Just about everyone has forgotten to close a Connection, File or a stream. With java 7 the standard verbose code blocks has been simplified with automatic resource management.

BeforeUsing 1.7
@Test
public void automatic_resouce_management_old() {

    File file = new File("");

    FileInputStream test = null;
    try {
        test = new FileInputStream(file);

        // do some operation

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {

        try {
            test.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}            
@Test
public void automatic_resouce_management() {

    try (FileInputStream fis = new FileInputStream("my-text-file.txt")) {

        System.out.println(fis.read());

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}            

Numeric literals with underscores

This is a huge for code readability and reducing error prone code. In the past I have found myself squinting and breaking apart trying to read "just how many" zeros are listed.

BeforeUsing 1.7
@Test
public void numberic_literals_with_underscores_old() {
    int thousand = 1000;
    int oneMillion = 1000000;
}
@Test
public void numberic_literals_with_underscores() {

    int thousand = 1_000;
    int oneMillion = 1_000_000;

}    

Improved exception handling

Another win for reducing duplicated code and improved readability is handling catching multiple exception types. Let say you have an exception block that emulates the same behavior. Instead of duplicating code, the catch clause allows you to specify multiple types of exceptions separated by the vertical bar (|).

BeforeUsing 1.7
@Test
public void improved_exception_handling_before() {

    try (FileInputStream fis = new FileInputStream("my-text-file.txt")) {

        System.out.println(fis.read());
        
        myTest();

    } catch (MyException e) { 
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    
}            
@Test
public void improved_exception_handling() {

    try (FileInputStream fis = new FileInputStream("my-text-file.txt")) {

        System.out.println(fis.read());
        
        myTest();

    } catch (IOException | MyException e) {
        // log or handle
    } 
}            

New way to work with files

Following a very similar pattern of guava files, java 7 had a major overhaul in the file API. Reading lines from a file, finding free space and writing to a file all have been simplified. One helpful link is the Legacy File I/O Code page which has a helpful matrix from old to new. This snippet below will show how to read all lines in a file into an ArrayList.

@Test
public void new_file_system() throws IOException {
    Path path = Paths.get("my-text-file.txt");
    
    List<String> lines = Files.readAllLines(path, Charset.forName("UTF-8"));
    
    for (String line : lines) {
        System.out.println(line);
    }
}