Java 7: Try-With-Resources (AutoCloseable)

Another great thing introduced with Java 7 is the “try-with-resources” construct – previously known as Automatic Resource Management (ARM). This feature is part of Project Coin, which is an umbrella project for a set of small changes to the Java language. You can see my other post on Java 7: Project Coin for more info.

When you work with files, networks streams or databases you follow a common pattern.

  1. Open resources
  2. Perform operation
  3. Close resources

You have to wrap the code in a try-finally block to make sure the resources are closed even if an exception occurs. Take a look at this example that copies the contents of one file to another file.

    public void oldStyleCopyFile(File source, File target) {
        FileInputStream in = null;
        FileOutputStream out = null;
        try {
            in = new FileInputStream(source);
            out = new FileOutputStream(target);
            byte[] buffer = new byte[4096];
            int read;
            while ((read = in.read(buffer)) != -1) {
                out.write(buffer, 0, read);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

Java 7 introduces a new construct called try-with-resources. You can initialize the resources inside parenthesis between the try keyword and the opening bracket, and Java will automatically close them for you. This works for all resources that implement the AutoCloseable interface.

    public void newStyleCopyFile(File source, File target) {
        try (
                FileInputStream in = new FileInputStream(source);
                FileOutputStream out = new FileOutputStream(target);
        ) {
            byte[] buffer = new byte[4096];
            int read;
            while ((read = in.read(buffer)) != -1) {
                out.write(buffer, 0, read);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Java 7 also contains NIO.2 which improves file operations in Java, and adds several essential features that Java has been missing. For example, now you can copy a file in one line. As a bonus this method not only copies the file contents but also the file metadata!

    public void shortCopyFile(File source, File target) {
        try {
            Files.copy(source.toPath(), target.toPath());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Java 7: Project Coin

Java 7 is just around the corner. Sadly it does not contain the highly anticipated closures/lambda expressions, but instead it includes a set of small language changes developed under the codename “Project Coin”.

In this post I will explore the basic language changes.

Strings in switch

Yes, finally you can switch on string constants in switch statements!

    public void executeCommand(String command) {
        switch (command) {
            case "start":
                startService();
                break;

            case "stop":
                stopService();
                break;

            case "status":
                showStatus();
                break;

            default:
                unknownCommand();
        }
    }

 

Binary Literals and Underscores in Numeric Literals

If you work with computer graphics, signal processing or integrate with old native C libraries, you often have to perform bit-manipulations and bit-masking etc. For some strange reason Java only supported decimal, octal and hexadecimal literals. Java Coin adds support for binary literals with the 0b prefix, and now it is legal to use underscores inside all numeric literals to make them easier to read.

    public void numericLiterals() {
        int mask1 = 0b1000100010001000;
        int mask2 = 0b1000_1000_1000_1000;

        int color = 0xff_f0_fe_ff;

        int price = 1_000_000;

        double PI = 3.141_592_653_589_793d;
    }

 Type Inference for Constructing Instances of Generic Types

This feature is going to remove a lot the verbosity of generic types. Take for example this example of a Map of a List of Strings:

    public void createGenerics() {
        List<String> list = new ArrayList<String>();
        Map<String, List<String>> keyValues = new HashMap<String, List<String>>();
    }

    public void createWithDiamondOperator() {
        List<String> list = new ArrayList<>();
        Map<String, List<String>> keyValues = new HashMap<>();
    }

The first method demonstrates the old way of creating generified collections.

The second method demonstrates how you can save a lot of typing by using the diamond operator <> and let the compiler infer the types from the left hand side.

Multi-Catch Exceptions

If you want to perform the same exception handling for a set of Exception types you can now catch them in a single catch statement by separating the types with a pipe character

    public void multiCatch(Class<MultiCatch> myClass) {
        try {
            Method method = myClass.getMethod("sayHello");
        } catch (NoSuchMethodException | SecurityException e) {
            // common exception handling logic
        }
    }

Automatic Resource Management

The final part of Project Coin is support for automatic resource management, which I will explore in a separate blog post.