Saturday, May 22, 2010

New Features in Java 7 (Dolphin)

There are many interesting features coming up in Java 7 code named as Dolphin. Below, I will discuss about some of these features (in no priority order) which I came across. This is not a complete list and some of these features are still in implementation and may not make it to the final release.

Multi-Catch:

Current way:

try {
// Say some file parser code here...
} catch (IOException ex) {
// log and rethrow exception
} catch (ParseException ex) {
// log and rethrow exception
} catch (ClassNotFoundException ex) {
// log and rethrow exception
}

This can now become...

try {
// Say some file parser code here...
} catch (IOException ex | ParseException ex | ClassNotFoundException ex) {
// log and rethrow exception
}

Much more simple right? We can just put all the exceptions in the same line separated by |. Ofcourse, this is only convenient if we take the same action for all exceptions. If we want to do different actions for different exceptions (which would be a more common case), then we still have to catch them individually.

Final Rethrow:

Let's say that we have a method like this:

private void testFinalRethrow(final int a) throws IOException, ParseException {
// code which throws IOException and ParseException
}

Now, if we want to do some operation (say log the exception) upon catching these exceptions and before rethrowing them, we could modify the above method like this:

private void testFinalRethrow(final int a) throws IOException, ParseException {
try {
// code which throws IOException and ParseException
} catch (Exception ex) {
// Log exception
throw ex;
}
}

But, the problem with this is, compiler will not like this since the method does not throw Exception (It only throws IOException and ParseException, which are subtypes of Exception). We are now forced to add Exception to method signature, but we may not be able to do this if testFinalRethrow overrides a method which does not declare throwing Exception.

In Java7, we could simplify this by adding final keyword in catch block. We could modify the above method to look like this:

private void testFinalRethrow(final int a) throws IOException, ParseException {
try {
// code which throws IOException and ParseException
} catch (final Exception ex) { // Look at final keyword here
// Log exception
throw ex;
}
}

Using final keyword in catch block allows us to throw the exact exception subtype which happened. For example, if IOException happened, then IOException would be thrown, if ParseException happened, then ParseException would be thrown (instead of Exception being thrown). Final keyword allows us to throw the exact exception which happened without the need to add Exception to method signature.

Strings in switch:

Before we talk about strings in switch, do you know what are the types allowed in switch now? We could use byte, short, char, int and enum in Switches. With Java 7, Strings could also be used.

private void testStringSwitch(final String key) {
final String value = "test;
String value2 = "test2"
switch (key) {
case value:
break;
case "foo":
break;
case value2: // Non-final variables are not allowed
break;
case getStringValue(): // Method calls not allowed
break;
}
}

As the comment says, non-final variables and method calls cannot be used in Switch case.

Improved Type Inference:

Old Way: List<Integer> list = new ArrayList<Integer>()
Google collections: List<Integer> list = Lists.newArrayList()
New Way: List<String> list = new ArrayList<>(); (Look at <>).

Let's take a look at complex example:

Old Way:
List<Map<String, List<Double>>> myList =
new ArrayList<Map<String, List<Double>>>();
New Way:
List<Map<String, List<Double>>> myList = new ArrayList<>();

Binary Literals:

Do you know how to convert binary number to decimal in Java6?

You could do it this way:
Integer.parseInt("101010", 2);
But this is verbose, slow and could throw runtime exceptions.

New way:
int binary = 0b101010; // Much easier right?

Underscores in Numbers:

int phoneNumber = 123_555_1212;
long creditCardNumber = 1234_5678_9012_4456L;
long socialSecurityNumber = 123_45_6789L;

These are all valid declarations in Java7.
Underscores are ignored by compiler
int result = (1_2 + 23_8) / 5_0 (Result would be 5)

Automatic resource management:

Current Way:
static String readLineFromFile(String path)
throws IOException {
BufferedReader br = new BufferedReader(
new FileReader(path))
try {
return br.readLine();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

As you can see, this is verbose and this is what we do now.

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

Both fin and br would be automatically managed in Java7.

Immutable Collections:

Current way: We use Collections.unmodifiableList, Collections.unmodifiableSet, Collections.unmodifiableMap etc.,

New way: (groovy like syntax)

List myList = [ "foo", "bar", "value" ];
Set mySet = { "foo", "bar", "value" };
Map myMap =
{ "foo" : 1, "bar" : 2, "value" : 3 };

New way is more elegant and straightforward.

Retrieving elements from collection:

Current Way:

myList.get(0);
myMap.get("foo");

New Way:

myList[0];
myMap["foo"];

Null Handling:

This is one of my favorites. java.util.Objects class has 9 useful static methods.
Javadoc for this class: http://download.java.net/jdk7/docs/api/java/util/Objects.html

nonNull - Similar to google preconditions
toString methods- Handles null automatically
hash and hashCode methods - Does hashCode for single or multiple objects. Returns 0 if object is null.
equals and deepEquals - Handles null automatically. Deep equals handles arrays also.

This post talks about them in more detail - http://www.baptiste-wicht.com/2010/04/java-7-the-new-java-util-objects-class/

Monitor changes in file system:

This feature is very useful if your application needs to know about the changes in file system and update itself accordingly. Look at these classes in Java7:

WatchKey - http://java.sun.com/javase/7/docs/api/java/nio/file/WatchKey.html

Project JIGSAW:

As we all know, JDK is huge and the goal of this project is to modularize the JDK. Here is the home page of the project - http://openjdk.java.net/projects/jigsaw/. I hope this would help in reducing the footprint of the application which we ship to our users.

Concurrency:

Java7 has updates to handling concurrency and one of the new things is Fork/Join framework. This post discusses about it in detail - http://www.baptiste-wicht.com/2010/04/java-7-more-concurrency/

Dropped features:

No Swing application framework - It was originally intended to remove boilerplate code

Not adding JXDatePicker API to platform

IDE Support:

Both IDEA and Eclipse support JDK7 at compile level only i.e they can compile the source but advanced features like code complete etc., won't work

NetBeans 6.9 Beta has much better support for JDK7

Release Schedule:

Milestone 7 is the latest release
Milestone 8 to be released in June 2010
Final release will be (hopefully) in September 2010

10 comments:

kaqqao said...

I don't think "final rethrow" does what you described here. Check this post.

Flash said...

What about closures?

Unknown said...

"final rethrow" could rather look something like this:

try {
} catch (rethrow Exception e){
}

i.e. with a new keyword. Adding new keywords would do better than adding semantics to the existing keywords...

Nenahov said...

"Underscores are ignored by compiler
int result = 1_2 + 23_8 / 5_0 (Result would be 5)"

Maybe so?

int result = (1_2 + 23_8) / 5_0 (Result would be 5)

Raja said...

@Flash - It seems like closures will make it to Java 7. Look at this post from Stephen Colebourne - http://www.jroller.com/scolebourne/entry/closures_in_jdk_7

Raja said...

@veggen - Also, look at this post - http://www.baptiste-wicht.com/2010/05/better-exception-handling-in-java-7-multicatch-and-final-rethrow/

@Anton - I agree that using final for this purpose is not correct.

Anyway, I see little value in this feature and it comes with complexity also.

Raja said...

@RIM - Fixed braces in the code. That was a typo. Thanks.

Unknown said...

Anton, it's not new semantics. It's effectively a new optimization of an existing semantic. Java has always supported final in a catch (the try catch block with final will compile in java 6).

The new part is that if I catch 3 different exceptions by using a single generic catch (i.e., catch final Exception ex) and then rethrow it, the compiler will now be smart enough to check if any of the original exceptions need to be caught (i.e. not declared on the method signature). If not it'll let me throw "ex" even though the signature doesn't actually have "Exception" as a declared exception. Basically this is handy if the signature declares several checked exceptions that extend a common base class, that I want to handle the same way.

It's a little confusing if you're only familiar with it from this post, Raja got it very wrong.

Raja said...

@Mark - I corrected the final rethrow explanation in this post. It was confusing initially and after playing with it some more I can see how it works. Thanks for pointing out the problem.

Unknown said...

Hey thanks for your valuable information.Defintely found informational.
NaiveGeek.