7 new cool features in Java 7

The evolution of the Java language and VM continues! Mark Reinhold (Chief Architect of the Java Platform Group) announced yesterday that the first release candidate for Java 7 is available for download, he confirms that the final released date is planned for July 28.

For a good overview of the new features and what’s coming next in Java 8, I recommend this video on the Oracle Media Network, which features Adam Messinger, Mark Reinhold, John Rose and Joe Darcy. I think Mark sums up Java 7 very well when describing it as an evolutionary release, with good number “smaller” changes that make for a great update to the language and platform.

I had a chance to play a bit with the release candidate (made easier by the Netbeans 7  JDK 7 support!), and decided to list 7 features (full list is here) I’m particularly excited about. Here they are;

1. Strings in switch Statements (doc)

Did you know previous to Java 7 you could only do a switch on char, byte, short, int, Character, Byte, Short, Integer, or an enum type (spec)? Java 7 adds Strings making the switch instruction much friendlier to String inputs. The alternative before was to do with with if/else if/else statements paired with a bunch of String.equals() calls. The result is much cleaner and compact code.

    public void testStringSwitch(String direction) {
        switch (direction) {
             case "up":
                 y--;
             break;

             case "down":
                 y++;
             break;

             case "left":
                 x--;
             break;

             case "right":
                 x++;
             break;

            default:
                System.out.println("Invalid direction!");
            break;
        }
    }

2. Type Inference for Generic Instance Creation (doc)

Previously when using generics you had to specify the type twice, in the declaration and the constructor;

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

In Java 7, you just use the diamond operator without the type;

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

If the compiler can infer the type arguments from the context, it does all the work for you. Note that you have always been able do a “new ArrayList()” without the type, but this results in an unchecked conversion warning.

Type inference becomes even more useful for more complex cases;

// Pre-Java 7
// Map<String,Map<String,int>>m=new HashMap<String, Map<String,int>>();

// Java 7
Map<String, Map<String, int>> m = new HashMap<>();

3. Multiple Exception Handling Syntax (doc)

Tired of repetitive error handling code in “exception happy” APIs like java.io and java.lang.reflect?

try {
    Class a = Class.forName("wrongClassName");
    Object instance = a.newInstance();
} catch (ClassNotFoundException ex) {
    System.out.println("Failed to create instance");
} catch (IllegalAccessException ex) {
    System.out.println("Failed to create instance");
} catch (InstantiationException ex) {
   System.out.println("Failed to create instance");
}

When the exception handling is basically the same, the improved catch operator now supports multiple exceptions in a single statement separated by “|”.

try {
    Class a = Class.forName("wrongClassName");
    Object instance = a.newInstance();
} catch (ClassNotFoundException | IllegalAccessException |
   InstantiationException ex) {
   System.out.println("Failed to create instance");
}

Sometimes developers use a “catch (Exception ex) to achieve a similar result, but that’s a dangerous idea because it makes code catch exceptions it can’t handle and instead should bubble up (IllegalArgumentException, OutOfMemoryError, etc.).

4. The try-with-resources Statement (doc)

The new try statement allows opening up a “resource” in a try block and automatically closing the resource when the block is done.

For example, in this piece of code we open a file and print line by line to stdout, but pay close attention to the finally block;

        try {
            in = new BufferedReader(new FileReader("test.txt"));
            
            String line = null;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (in != null) in.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

When using a resource that has to be closed, a finally block is needed to make sure the clean up code is executed even if there are exceptions thrown back (in this example we catch IOException but if we didn’t, finally would still be executed). The new try-with-resources statement allows us to automatically close these resources in a more compact set of code;

       try (BufferedReader in=new BufferedReader(new FileReader("test.txt")))
       {
            String line = null;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException ex) {
            ex.printStackTrace(); 
        }

So “in” will be closed automatically at the end of the try block because it implements an interface called java.lang.AutoCloseable. An additional benefit is we don’t have to call the awkward IOException on close(), and what this statement does is “suppress” the exception for us (although there is a mechanism to get that exception if needed, Throwable.getSuppressed()).

5. Improved File IO API (docs 1, 2)

There are quite a bit of changes in the java.nio package. Many are geared towards performance improvements, but long awaited enhancements over java.io (specially java.io.File) have finally materialized in a new package called java.nio.file.

For example, to read a small file and print all the lines (see example above);

       List<String> lines =  Files.readAllLines(
       FileSystems.getDefault().getPath("test.txt"), StandardCharsets.UTF_8);
       
       for (String line : lines) System.out.println(line);

java.nio.file.Path is an interface that pretty much serves as a replacement for java.io.File, we need a java.nio.file.FileSystem to get paths, which you can get by using the java.nio.file.FileSystems factory (getDefault() gives you the default file system).

java.nio.file.Files then provides static methods for file related operations. In this example we can read a whole file much more easily by using readAllLines(). This class also has methods to create symbolic links, which was impossible to do pre-Java 7. Another feature long overdue is the ability to set file permissions for POSIX compliant file systems via the Files.setPosixFilePermissions method. These are all long over due file related operations, impossible without JNI methods or System.exec() hacks.

I didn’t have time to play with it but this package also contains a very interesting capability via the WatchService API which allows notification of file changes. You can for example, register directories you want to watch and get notified when a file is added, removed or updated. Before, this required manually polling the directories, which is not fun code to write.

For more on monitoring changes read this tutorial from Oracle.

6. Support for Non-Java Languages: invokedynamic (doc)

The first new instruction since Java 1.0 was released and introduced in this version is called invokedynamic. Most developers will never interact or be aware of this new bytecode. The exciting part of this feature is that it improves support for compiling programs that use dynamic typing. Java is statically typed (which means you know the type of a variable at compile time) and dynamically typed languages (like Ruby, bash scripts, etc.) need this instruction to support these type of variables.

The JVM already supports many types of non-Java languages, but this instruction makes the JVM more language independent, which is good news for people who would like to implement components in different languages and/or want to inter-operate between those languages and standard Java programs.

7. JLayerPane (doc)

Finally, since I’m a UI guy, I want to mention JLayerPane. This component is similar to the one provided in the JXLayer project. I’ve used JXLayer many times in the past in order to add effects on top of Swing components. Similarly, JLayerPane allows you to decorate a Swing component by drawing on top of it and respond to events without modifying the original component.

This example from the JLayerPane tutorial shows a component using this functionality, providing a “spotlight” effect on a panel.

You could also blur the entire window, draw animations on top of components, or create transition effects.

And that’s just a subset of the features, Java 7 is a long overdue update to the platform and language which offers a nice set of new functionality. The hope is the time from Java 7 to 8 is a lot shorter than from 6 to 7!

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

23 Comments »

 
  • Dario says:

    All pretty cool except #1 which promotes the bad practice of using string literals – use enum instead!

  • Augusto says:

    I think you are probably correct, although I can see where for simple things where your input is already a string, this method is very convenient.

  • Narada says:

    Dario – that is such a small minded and idiotic comment. The scope of strings in switch statement is much wider than simply using it for constants. An obvious example would be if I wanted to switch on a string coming in as a method argument. Should I make that into an enum just to be able to switch on it? Taking your argument forward perhaps you'd like to eliminate strings altogether and just use enums because simply the existence of strings promotes use of string literals?

  • Augusto says:

    Narada, funny you say that, that's what I was thinking in the code example … processing commands from a text/console based command.

  • Estefania Soto says:

    I remember asking about #1 to my professor and he said it would be included in Java 7. I love number two it was redundant in my opinion.An as a student of Java in college seemed unnecessary

  • PhiLho says:

    "Sometimes developers use a “catch (Exception ex) to achieve a similar result, but that’s a dangerous idea because it makes code catch exceptions it can’t handle and instead should bubble up (IllegalArgumentException, OutOfMemoryError, etc.)."

    Well, catching Exception won't catch OutOfMemoryError, since the latter is… an Error.

    That's why catching Exception is "acceptable" (even if not good practice in production code) while catching Throwable is not at all.

  • SteveRob says:

    Pretty cool features. For a beginner programmer like me, the standout features are string in switch, muticatch blocks and resource autoclose tryblock. Thanks for organizing and presenting the features like this…. :)

  • Pierluigi Vernetto says:

    a step forward, but still so far away from the elegance and conciseness of groovy.
    incidentally I find Nevada language shocking, but there is no way to report the abuse

  • Mohammed Ziya says:

    Great features!!

  • [...] is a long overdue update to the platform and language which offers a nice set of new functionality. Read more… Categories: Oracle  Java     Share | Related [...]

  • Fernando Franzini says:

    Amazing!!!

  • camilo lopes says:

    good post and features!! :)

  • Arun says:

    I agree with Dario regarding using Strings in Switch (item #1). Using Enums brings in more discipline, And makes it easy to maintain the code.

    Also, item #2 is very much a convenience rather than an improvement…

  • The Master says:

    People insisting on enumerators are trading one problem for another. After your code is compiled and tested, there is no advantage with one over the other. Enums are a crutch for people dependent on the auto-complete feature of today's IDE editor. If I have a new string, no big deal, just change the switch statement. If I have a new enum, first I have to change the enum class, then I can change the switch statement. It's just silly and I've yet to see anyone prove you are better off with enums.

  • Dave says:

    Enums are much more than simple string replacements. True, string constants can provide a single point of maintenance. But if you use an enum on a method call, you guarantee that the value submitted is one that you are prepared to handle. And enums provide navigability. For example, if I have a method:

    private void doSomething (String codeValue) …

    … how do you know what codes are meaningful to the method? The might be defined as constants in a class somewhere in the code base, but where will you look? On the other hand, if the method is:

    private void doSomething (CodeValue codeValue)…

    …the method tells you where to look to find out what is valid. Just look at the CodeValue enum.

    Enums are not always the answer. Sometimes you're reading values from a config file, for example. But when they can be used, they're great.

  • Mike Kolcun says:

    In your complex inference example.

    We're still not able to use primitive types in generics, so
    Map<String, Map<String, int>> m = new HashMap<>();

    won't work, the compiler will throw an error saying that we must use an object.

  • makpandian says:

    Really Nice. Thanks

  • Githin says:

    one diamond operator is also available, heard so.

  • Jeet says:

    Good features.. I like most the Switch case and diamond operator..
    http://www.javaprogrammings.info/

  • saravana says:

    Thanks for giving such a wonderful things about java….

  • my site says:

    I keep in thoughts asking about #1 to my speaker and he said it would be engaged in Java 7. I really like number two it was recurring in my perspective.An as an outstanding student of Java in college seemed unnecessary

  • milliemillie says:

    People requiring on enumerators are dealing one issue for another. After your rule is collected and examined, there is no benefits with one over the other. Enums are a crutch for individuals reliant on the auto-complete function of modern IDE manager. If I have a new sequence, no big cope, just modify the change declaration. If I have a new enum, first I have to modify the enum category, then I can modify the change declaration. It's just foolish and I've yet to see anyone confirm you are better off with enums.

 

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>