Project Coin: Java 7 Language Inhancement

Project Coin:

The goal of Project Coin is to determine what set of small language changes should be added to Java 7. We probably know about them, if not learn it- http://openjdk.java.net/projects/coin/coin_proposal_form_v1.0.html

So here today I’m going to share about a collection of small yet effective new features implemented in project coin.

So the enhancements are in –

  • Strings in switch
  • Binary integral literals and underscores in numeric literals
  • Multi-catch and more precise rethrow
  • Improved type inference for generic instance creation (diamond)
  • try-with-resources statement
  • Simplified varargs method invocation

String in switch:

Java’s switch statement allows you to write an efficient multiple-branch statement without lots and lots of ugly nested ifs, like this:

public void printDay(int day) {
switch (day) {
case 1:
System.out.println("Sunday");
break;
case 2:
System.out.println("Monday");
break;
// more cases will be here
default:
System.out.println("Error");
break;
}
}

In java 6 and earlier version of Java, the values for the cases can be only byte, char, short, or int or their reference-type equivalents Byte, Character, Short and Integer and enum. But in Java 7 the spec has been extended to allow for Strings to be used as well. Example-

public void printDay(String day) {
switch (day) {
case "Sunday":
System.out.println("শনিবার");
break;
case "Monday":
System.out.println("রবিবার");
break;
// more cases will be here
default:
System.out.println("Error");
break;
}
}

Binary Literals:

Before Java 7, if you’d wanted to manipulate a binary value, you would do like-

int x = Integer.parseInt("1100110", 2);


This is a lot of typing just to ensure that x ends up with that bit pattern   (which is 102 in decimal,  by  the  way).  There’s worse to come though. It:

  • Is really verbose.
  • Has a performance hit for that method call.
  • Means you’d have to know about the two-argument form of parseInt().
  • Requires you to remember the detail of how parseInt() behaves when it has two args.
  • Makes life hard for the JIT compiler.
  • Is representing a compile-time constant as a runtime expression (so it can’t be used as a value in a switch statement).
  • Will give you a runtime exception (but no compile-time exception) if you get a typo in the binary value.

Fortunately, with the advent of Java 7, we can now write:

int x = ob1100110;

Now we’ll not face the above problems.

Underscores in numbers:

We all know that human mind is quite different from computer’s CPU. Human are not comfortable to handle quite long string of number. That’s why we invented hexadecimal number. That is we find easier ABC420 instead of 101010111100010000100000. So there is a way to deal with long strings of numbers is to break them up. Like our phone number, we break it like-

088-01671-865012

Other long strings of numbers have separators too:

$100,000,000 (Large sums of money)

08-92-96 (UK banking sort codes)

Unfortunately, both ‘,’ and ‘–‘ have too many possible meanings  within the realm of handling numbers while programming,  so we can’t use either of those as a separator. So here project coin borrow idea from an idea from Ruby and introduced the underscore ‘_’ as a separator. So, you can write 100_000_000. Example –

long cellNo = 088_01671_865012L;

Note that this is  just a bit of easy-on-the-eyes compile time syntax – the compiler just strips out those underscores and stores the usual digits.

Here is some other example:

int x1 = _52; // This is an identifier, not a numeric literal.

int x2 = 5_2; // OK. (Decimal literal)

int x2 = 52_; // Illegal. (Underscores must always be between digits)

int x3 = 5___2; // OK. (Decimal literal.)

int x4 = 0_x52; // Illegal. Can’t put underscores in the “0x” radix prefix.

int x5 = 0x_52; // Illegal. (Underscores must always be between digits)

int x6 = 0x5_2; // OK. (Hexadecimal literal)

int x6 = 0x52_; // Illegal. (Underscores must always be between digits)

int x6 = 0x_; // Illegal. (Not valid with the underscore removed)

int x7 = 0_52; // OK. (Octal literal)

int x7 = 05_2; // OK. (Octal literal)

int x8 = 052_; // Illegal. (Underscores must always be between digits)

These examples above is borrowed from: http://stackoverflow.com/questions/6212558/java-7-underscore-in-numeric-literals

Improved exception handling:

There are two parts to this improvement – multi-catch and, effectively, final rethrow.

  • Multicatch : You’ll now be able to catch multi exceptions type in one catch block
  • Final Rethow : Allows you to catch an exception type and it’s subtype and rethrow it without having to add a throws clause to the method signature.

Let see how we handle exception-

try {
//do some code here
//bla bla bla
} catch (FileNotFoundException e) {
// Log or printStackTrace
throw e;
} catch (ParseException e) {
// Log or printStackTrace
throw e;
} catch (ConfigurationException e) {
// Log or printStackTrace
throw e;
} catch (IOException iox) {
// Log or printStackTrace
throw e;
}

This code is fine, but really heavy for nothing interesting. In in Java 7, there is an interesting solution.


try {
//do some code here
//bla bla bla
} catch (FileNotFoundException | ParseException | ConfigurationException  | IOException e) {
// Log or printStackTrace
//or do whatever you want
throw e;
}

It is something interesting.

And the second improvement is a little more complicated. Imagine that you want to catch all exceptions, make several operations and then rethrow it. The code isn’t hard to make, but the big problem is that you must add a throws clause to your method signature to manage the new exception launched by your code and this is not the objective. Now, you can do that without adding an exception throws clause:

try {
//do some code here
//bla bla bla
} catch (final Throwable ex) {
// some more code
throw ex;
}
[/sourcecode

Using the final keyword it allows you to throw an exception of the exact dynamic type that will be throwed. So if an IOException occurs, an IOException will be throwed.

<strong>Diamond syntax: </strong>

We probably very much familiar with this type of code:


Map<String,Map<String, String>> userList = new HashMap<String,Map<String,String>>();

That’s quite a mouthful, and almost half of it is just duplicated characters. Wouldn’t it be better if we could just write something like the code below, and have the compiler just infer the type information on the right hand side?

Map<String, Map<String, String>> userList = new HashMap<>();

And this is the magic of project coin. In java 7, the shortened form for declarations like that is entirely legal.

Try-with-resources:

For example we want to read from a URL-based stream URL and write and write to a file.

InputStream is = null;
try {
File file = new File("output.txt");
URL url = new URL("http://blog.codexplo.org/2011/08/10/functional-language-rule-future-programming-world/");
is = url.openStream();
OutputStream out = new FileOutputStream(file);
try {
byte[] buf = new byte[4096];
int n;
while ((n = is.read(buf)) >= 0)
out.write(buf, 0, n);
} catch (IOException iox) {
// Handles exception (could be read or write)
} finally {
try {
out.close();
} catch (IOException closeOutx) {
// Can’t do much with exception
}
}
} catch (FileNotFoundException fnfx) {
// Handles exception
} catch (IOException openx) {
// Handles exception
} finally {
try {
if (is != null)
is.close();
} catch (IOException closeInx) {
// Can’t do much with exception
}
}

The key point here is that, when handling external resources, Murphy’s Law applies – anything can go wrong at any time:

  1. The InputStreamcan fail:
    1. To open from the URL.
    2. To read from it.
    3. To close properly.
    4. The file corresponding to the 2 OutputStreamcan fail:
      1. To open.
      2. To write to it.
      3. To close properly.
      4. Or have some combination of more than one of the 3 above.

This last possibility is actually where a lot of the headaches come from – the possibility of some combination of exceptions is very difficult to deal with well.

Let see how we could write it in Java 7,

 

try ( OutputStream fos = new FileOutputStream(file);

InputStream is = url.openStream() ) {
byte[] buf = new byte[4096];
int len;
while ((len = is.read(buf)) > 0) {
fos.write(buf, 0, len);
}
} catch (IOException | FileNotFoundException e) {
// If file is not fo
}


Much cleaner, right! With that code, the resources are automatically closed after the try. You need not do it manually.

Simplified varargs method invocation:

This is one of the simplest changes of all – it just moves a warning about type information for quite a specific case where varargs (variable arity) combines with generics in a method signature.

When a programmer tries to invoke a *varargs* (variable arity) method with a non-verifiable varargs type, the compiler currently generates an “unsafe operation” warning. JDK 7 moves the warning from the call site to the method declaration. This will enable API designers to use varargs due to the reduction of warnings reported

Read more about it from here: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000217.html

References:

  1. http://www.baptiste-wicht.com/2010/05/better-exception-handling-in-java-7-multicatch-and-final-rethrow/
  2. http://thecoderlounge.blogspot.com/2011/07/java-7-support-in-eclipse-jdt-beta-part_14.html
  3. http://blogs.oracle.com/darcy/entry/project_coin_literal_grammar_hackery
  4. http://code.joejag.com/2009/new-language-features-in-java-7/
  5. http://blogs.oracle.com/darcy/entry/project_coin_multi_catch_rethrow
  6. JavaTech Journal, Issue June 2011
  7. http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000217.html
  8. http://openjdk.java.net/projects/coin/
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s