JDK7 Project Coin Primer

Although I knew about the small language enhancements going into JDK7, named Project Coin, quite some time back it was only today that I got around to actually coding and trying them all out primarily due to prior laziness and poor editor support. Yes I know – there’s plenty of docs on Project Coin out there already. This is mine.

And now that JDK7 actually has a finite number of steps in its release schedule and is scheduled for release on 28/07/2011 we know our efforts in learning the new feature set are not going to waste and that very soon we’ll be able to write production code with this knowledge to make the industry a better place which is ultimately what is important.

Here I present a quick primer for the uninitiated. The small language enhancements going into JDK7 are as follows.

  1. Strings in switch
  2. Binary integral literals
  3. Underscores in numeric literals
  4. Multi-catch and more precise rethrow
  5. Improved type inference for generic instance creation(diamond)
  6. try-with-resources statement
  7. Simplified varargs method invocation

Below I provide one example per feature that will take you through each feature in a flash.

Strings in switch

A long overdue and seemingly basic feature but better late than never.

[java]
package name.dhruba.kb.jdk7;

public class StringsInSwitch {

public static void main(String[] args) {
for (String a : new String[]{"foo", "bar", "baz"}) {
switch (a) {
case "foo":
System.out.println("received foo!");
break;
case "bar":
System.out.println("received bar!");
break;
case "baz":
System.out.println("received baz!");
break;
}
}
}

}
[/java]

Binary integral literals

I can’t say I’ve ever felt the absence of this rather unusual feature. Though it seems it was felt compelling enough to be added in. This is primarily a readability advantage – a semantic representation.

[java]
package name.dhruba.kb.jdk7;

public class BinaryLiterals {

public static void main(String[] args) {

// An 8-bit ‘byte’ literal.
byte aByte = (byte) 0b00100001;

// A 16-bit ‘short’ literal.
short aShort = (short) 0b1010000101000101;

// Some 32-bit ‘int’ literals.
int anInt1 = 0b10100001010001011010000101000101;
int anInt2 = 0b101;
int anInt3 = 0B101; // The B can be upper or lower case.

// A 64-bit ‘long’ literal. Note the "L" suffix.
long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;

}

}
[/java]

Underscores in numeric literals

I’ve often found myself adding javadoc to make a constant declaration clearer. This makes them somewhat clearer which is definitely helpful.

[java]
package name.dhruba.kb.jdk7;

public class UnderScoredLiterals {

public static void main(String[] args) {

long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;

}

}
[/java]

Multi-catch

The multi-catch is very useful indeed and significantly reduces the number of lines of code to do such things from before.

[java]
package name.dhruba.kb.jdk7;

public class MultiCatchException {

static class Exception1 extends Exception {}
static class Exception2 extends Exception {}

public static void main(String[] args) {
try {
boolean test = true;
if (test) {
throw new Exception1();
} else {
throw new Exception2();
}
} catch (Exception1 | Exception2 e) {
}
}

}
[/java]

More precise exception rethrow

The more precise rethrow is a tricky one to understand. See if you can spot what the new feature is in the example below. Will it compile on pre-java-7? If not how would it need to be changed to compile on pre-java-7? The answers lie after the example.

[java]
package name.dhruba.kb.jdk7;

public class MorePreciseExceptionRethrow {

static class Exception1 extends Exception {}
static class Exception2 extends Exception {}

public static void main(String[] args) throws Exception1, Exception2 {
try {
boolean test = true;
if (test) {
throw new Exception1();
} else {
throw new Exception2();
}
} catch (Exception e) {
throw e;
}
}

}
[/java]

On Java 6 compiling the above gives the following exception.

[text]
Foo.java:18: unreported exception java.lang.Exception; must be caught or declared to be thrown
throw e;
^
1 error
[/text]

This can be fixed for Java 6 by changing:

[java]public static void main(String[] args) throws Exception1, Exception2 {[/java]

to:

[java]public static void main(String[] args) throws Exception {{[/java]

So now you see the improvement that Java 7 offers with this feature. You can be more precise in the declaration of the exceptions that you rethrow. Very nice indeed.

Improved type inference for generic instance creation(diamond)

Oh my God. Thank you Oracle for this feature. I breathe a huge sigh of relief. How long has it taken to get this out? How many keystrokes and keyboards have I wasted over the period of my career? And how much of a penalty have the tips of my fingers paid over the years for typing out the right hand side of a generic assigment? This curse is no more. Particularly note the constructor inference which is new to Java 7 also.

[java]
package name.dhruba.kb.jdk7;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GenericDiamondTypeInference {

static class MyClass <X> {
<Y> MyClass(Y y) {
}
}

public static void main(String[] args) {

// constructor inference
// <X> = <Integer>, <Y> = <String>
MyClass<Integer> myClass1 = new MyClass<>("");

// standard stuff
List<String> list = new ArrayList<>();
Map<String, List<String>> map = new HashMap<>();

}

}
[/java]

try-with-resources statement

This is simply beautiful and incredibly reassuring for the simple reason that resource closing is not only automatic and requires a lot less code but if in the examples below multiples exceptions are thrown (i.e. one in the closing of the resource and one in the use of the resource) then not only does the latter not get swallowed (unlike pre-java-7) but finally you can access all suppressed exceptions (i.e. the former) via the new API.

[java]
package name.dhruba.kb.jdk7;

public class TryWithResources {

static class MyResource1 implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("MyResource1 was closed!");
}
}

static class MyResource2 implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("MyResource2 was closed!");
}
}

public static void main(String[] args) throws Exception {
/*
* close() methods called in opposite order of creation
*/
try (MyResource1 myResource1 = new MyResource1();
MyResource2 myResource2 = new MyResource2()) {}
}

}
[/java]

NOTE: In the above example the resources are closed in an order opposite to their order of creation.

Simplified varargs method invocation

This was a very tricky one to investigate. It’s still not clear what ‘simplified varargs method invocation’ is referring to but one difference (improvement) I was able to narrow down was that of a more specific and helpful warning that jdk7 adds to certain varargs code as below.

[java]
package name.dhruba.kb.jdk7;

import java.util.Collections;
import java.util.List;
import java.util.Map;

public class BetterVarargsWarnings {

static <T> List<T> foo(T… elements) {
return null;
}

static List<Map<String, String>> bar() {
Map<String, String> m = Collections.singletonMap("a", "b");
return foo(m, m, m);
}

}
[/java]

In Java 6 the above generates the following warning.

[text]
/Users/dhruba/NetBeansProjects/SwitchTest/src/name/dhruba/kb/jdk7/BetterVarargsWarnings.java:15: warning: [unchecked] unchecked generic array creation of type java.util.Map<java.lang.String,java.lang.String>[] for varargs parameter
return foo(m, m, m);
^
1 warning
[/text]

In Java 7 however an additional warning is generated.

[text]
/Users/dhruba/NetBeansProjects/SwitchTest/src/name/dhruba/kb/jdk7/BetterVarargsWarnings.java:9: warning: [unchecked] Possible heap pollution from parameterized vararg type T
static <T> List<T> foo(T… elements) {
^
where T is a type-variable:
T extends Object declared in method <T>foo(T…)
/Users/dhruba/NetBeansProjects/SwitchTest/src/name/dhruba/kb/jdk7/BetterVarargsWarnings.java:15: warning: [unchecked] unchecked generic array creation for varargs parameter of type Map<String,String>[]
return foo(m, m, m);
^
2 warnings
[/text]

Compiling Java 7

  • Download JDK7. I used OpenJDK OS X Build on my Mac.
  • Download Netbeans 7 which is what I used again on the Mac. Or Intellij 10.5.
  • Be happy. There’s no link for that but if you don’t feel this at this point you may want to think of a change of career.

Thanks to LingPipe for linking to this post.

One thought on “JDK7 Project Coin Primer

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s