Sunday, 13 February 2011

New language features with JDK7 (Project Coin)

With JDK 7 already passed its Feature Complete stage (M11) and currently in its Developer's Review stage (M12), it will be interesting to list the feature modifications that have been made in this release.

In this blog, I will primarily focus on the language enhancements that have been a part of this JDK release (Project Coin - covered in M11). Some of these I was really looking forward to... :)

1) Strings in Switch: With this release, the Switch statement can be based on String expressions as well. e.g. let us consider the following code:

String s = ...... ;
switch(s) {
case "abc":
processABC():
break;
case "def":
case "ghi"
processDEForGHI();
break;
case "xyz":
processXYZ();
break;
default:
processDEFAULT();
break;

2) Automatic Resource Management: This is a form of 'try-catch' that declares one or more resources (a resource is an object that must be closed manually e.g. OutputStream, InputStream). The scope of these resources is limited to the statement. When the statement completes, normally or abruptly, all of its resources are closed automatically.

Presently, this is how a resource is handled:

static String readLineFromFile(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));

try {
return br.readLine();
} finally {
br.close();
}
}

In the case, when both readLine and close invocations throw exception, the latter exception takes priority over the former. As of now, the only way around is to ignore any exception thrown by the close invocation. This can prove to be an issue, more so in case of a writer or OutputStream operation.
With automatic resource management in place, the above sample code will look something like:

static String readLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))){
return br.readLine();
}
}

3) Improved Type Inference for Generic Instance Creation (diamond): This feature tries to simplify the parametrized assignment. Consider the following example:

Map<String, List<String>> fooMap = new HashMap<String, List<String>>();

This is rather lengthy and can now rather be replaced with:
Map<String, List<String>> fooMap = new HashMap();

Advantage is the simplicity it provides to assignments, hence cleaner code. Conversely, it can be argued that though a code like Map = new HashMap(); looks cleaner, but then for backward compatibility, new HashMap(); denotes a raw type. Hence a sense of conformity is missing as of now. But this is just a minor drawback, I would say. For this reason, a provision has been made to add empty <>, like: Map<String, List<String>> fooMap = new HashMap<>();

4) Simplified Varagrs Method Invocation: As of now, when a user tries to invoke a 'varargs', the compiler generates an "unsafe operation" warning. Now, this warning has been moved from the call site to the method declaration. This significantly reduces the number of warnings reported and suppressed by the programmer.

e.g. Before, a varargs declaration would have been something like:

static <T> List<T> asList(T... elements) { ... }

static List<Callable<String>> stringFactories() {
Callable<String> a, b, c;
...
*// Warning: **"uses unchecked or unsafe operations"*
return asList(a, b, c);
}

Now it will be like:

*// Warning: **"enables unsafe generic array creation"*
static <T> List<T> asList(T... elements) { ... }

static List<Callable<String>> stringFactories() {
Callable<String> a, b, c;
...
return asList(a, b, c);
}


5) JVM level source-code syntax (JSR 292): These primarily include the following:

a) Dynamic Invocation: The interface java.dyn.Dynamic may be used with the static call syntax to form an invoke dynamic call site. The arguments may be of any number and any type. Hence, theoretically java.dyn.Dynamic appears to have infinite number of methods, of every possible name and signature.
e.g.
Object obj = Dynamic.getDynamicLink();

An invoke dynamic call is linked to a target method under control of an application-defined bootstrap method and the linkage state is defined by a method handle (explained below) with the same type descriptor as the call itself.


b) Method Handle Invocation: Method handles (java.dyn.MethodHandle) provides the linkage state behind any invoke dynamic instruction. Like Dynamic calls, a method handle also accepts any number of type and signature, which means that it can also have infinite number of calls to method "invoke".
e.g.
MethodHandle mh = ...
mh.invoke();

c) Exotic Identifiers: The identifiers can now be any sequence of characters (with minor restrictions). Certainly this will enable in more user-friendly naming and hence cleaner and more maintainable code.
e.g.
int #"valid variable name" = 100;
System.out.println(#"valid variable name"); //this will print 100

d) Conversion rule for Interface Dynamic: Type Dynamic also serves a purpose of a wildcard type. As a mere reference, it can be freely converted to any other type and to object and as a cast, it can be converted to any type. Along with invoke dynamic syntax, it allows dynamic method calls chaining.
e.g.
Dynamic dynObj = (any type of expression);
Object obj = x.foo("ABC").bar(100).baz();

The JSR292 changes basically allow Java to interoperate with new JVM languages. It also enables Java to serve well as a language implementation or systems programming language.

These are the language changes that I have come across with JDK 7. More information can be found at http://blogs.sun.com/darcy/entry/project_coin_final_five
I am certainly now looking forward for JDK7 to be officially released (should be sometime in the second half of 2011). Enjoy coding... :)

No comments: