'API Enhancements in Java SE 7' post illustration

API Enhancements in Java SE 7

avatar

Recently released Java 7 has a lot of useful API enhancements such as the automatic resource management, multi-catch statements, switch statement with strings, binary literals and improved numeric literals. This post is a quick roundup of the new features, which should help you to get a full picture of Java 7 syntax in a short time.

Automatic Resource Management

The try-with-resources statement is a 'try' that accepts one or more resources which will be closed automatically when the statement completes. Resources must implement the AutoCloseable or Closeable interface to be used with the try-with-resources block:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Resource implements AutoCloseable {

    public void doAction() throws Exception {
        // throws the exception when doAction() is being called
        throw new Exception("Resource action exception");
    }

    @Override
    public void close() throws Exception {
       // throws the exception when the resource is being closed
       throw new Exception("Resource close exception");
    }
}
1
2
3
4
5
6
7
8
9
10
11
try (Resource resource = new Resource()) {
    // the resource will be automatically closed when doAction()
    // throws the exception
    resource.doAction();
} catch (Exception e) {
    // catches the exception thrown by the doAction() method,
    // the exception thrown by the close() method is suppressed,
    // but still can be retrieved with Throwable.getSuppressed()
    e.getSuppressed()[0] // returns the "Resource close exception"
    throw e;             // throws the "Resource action exception"
}

Catching multiple exception types

A single catch block can handle several different exception types, which was impossible in prior Java versions. For example, the try-catch:

1
2
3
4
5
catch (ConnectException ex) {
     throw new APIException("Cannot connect to the database");
catch (DBConnectException ex) {
     throw new APIException("Cannot connect to the database");
}

can be replaced with:

1
2
3
4
catch (ConnectException | DBConnectException ex) {
    // handles both the ConnectException and the DBConnectException
    throw new APIException("Cannot connect to the database");
}

Strings in switch statements

Java 7 finally allows to use a String object in the expression of a switch statement. The new switch compares strings using the String.equals() method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public String getPlanetSize(String planet) {
   String size;
   switch (planet) {
       case "Earth":
           size = "Small";
           break;
       case "Jupiter":
       case "Saturn":
           size = "Large";
           break;
       // ---------------
       default:
           throw new IllegalArgumentException("Invalid pl: " + planet);
   }
   return size;
}

This code works the same as the following if-then-else chain:

1
2
3
4
5
6
7
8
9
10
11
12
public String getPlanetSize(String planet) {
   String size;
   if (planet.equals("Earth")) {
       size = "Small";
   } else if (planet.equals("Jupiter") || planet.equals("Saturn")) {
       size = "Large";
   // --------------
   } else {
       throw new IllegalArgumentException("Invalid planet name: " + planet);
   }
   return size;
}

The switch statement, of course, is much more preferable choice, as the code generated by a compiler will be more efficient.

Binary literals

New binary literals must be prefixed with 0b or 0B, for example:

1
2
3
int i1 = 0b101;
// or
int i2 = 0B101;

You can also use binary literals to express integral types:

1
2
3
4
byte b = 0b10010010 // up to 8 bit
short s = 0b1001001010010010 // up to 16 bit
int i = 0b10010010100100101001001010010010 // up to 32 bit
long l = 0b1001001010010010100100101001001010010010100100101001001010010010 //up to 64 bit

Binary literals are very convenient in bitwise and bitshift operations:

1
2
3
4
5
byte hex = 0xA | 0x9;
byte binary = 0b00001010 | 0b00001001;
assert binary == hex;
assert binary == (byte)0xB;
assert binary == (byte)0b00001011

Underscores in numeric literals

Any numeric literal can be separated into groups using underscore characters. The literal will be invalid if it has underscores that are placed:

  • before or after a decimal point
  • before F, f, D, d, ... suffixes
  • at the literal beginning or end

Correct:

1
2
3
int i1 = 10_103;      // 10103
int i2 = 10______103; // 10103
int i3 = 0_12;        // 012 - octal literal

Incorrect:

1
2
3
4
float f = 10_.3432F;
long l = 10_L;
int i = 12_;
int x = 0_x12;

Underscores can be used to visually separate digits and make code more readable, for example, binary or hexadecimal literals can be separated by bytes:

1
2
int i1 = 0b10010010_10010010_10010010_10010010
int i2 = 0x92_92_92_92
Conclusion

These are almost all syntax changes in Java 7, and yes, it would be nice to have more syntactic sugar. The good news is the Java 8 release is coming soon, which, with lambda expressions and method references, promises to have a lot of extremely interesting features and improvements.

If you're looking for a developer or considering starting a new project,
we are always ready to help!