Java 7 Feature Overview
Today’s post will take us through each of the Project Coin features – a collection of small language enhancements that aren’t groundbreaking, but are nonetheless useful for any developer able to use JDK 7.
I’ve come up with a bank account class that showcases the basics of Project Coin features.
Take a look…
public class ProjectCoinBanker { private static final Integer ONE_MILLION = 1_000_000; private static final String RICH_MSG = "You need more than $%,d to be considered rich."; public static void main(String[] args) throws Exception { System.out.println(String.format(RICH_MSG, ONE_MILLION)); String requestType = args[0]; String accountId = args[1]; switch (requestType) { case "displayBalance": printBalance(accountId); break; case "lastActivityDate" : printLastActivityDate(accountId); break; case "amIRich" : amIRich(accountId); break; case "lastTransactions" : printLastTransactions(accountId, Integer.parseInt(args[2])); break; case "averageDailyBalance" : printAverageDailyBalance(accountId); break; default: break; } } private static void printAverageDailyBalance(String accountId) { String sql = String.format(AVERAGE_DAILY_BALANCE_QUERY, accountId); try ( PreparedStatement s = _conn.prepareStatement(sql); ResultSet rs = s.executeQuery(); ) { while (rs.next()) { //print the average daily balance results } } catch (SQLException e) { // handle exception, but no need for finally to close resources for (Throwable t : e.getSuppressed()) { System.out.println("Suppressed exception message is " + t.getMessage()); } } } private static void printLastTransactions(String accountId, int numberOfTransactions) { List transactions = new ArrayList<>(); //... handle fetching/printing transactions } private static void printBalance(String accountId) { try { BigDecimal balance = getBalance(accountId); //print balance } catch (AccountFrozenException | ComplianceViolationException | AccountClosedException e) { System.err.println("Please see your local branch for help with your account."); } } private static void amIRich(String accountId) { try { BigDecimal balance = getBalance(accountId); //find out if the account holder is rich } catch (AccountFrozenException | ComplianceViolationException | AccountClosedException e) { System.out.println("Please see your local branch for help with your account."); } } private static BigDecimal getBalance(String acccountId) throws AccountFrozenException, AccountClosedException, ComplianceViolationException { //... getBalance functionality } }
Briefly, our ProjectCoinBanker class demonstrates basic usage of the following Project Coin features.
- Underscores in numeric literals
- Strings in switch
- Multi-catch
- Type inference for typed object creation
- try with resources and suppressed exceptions
First of all, underscores in numeric literals are pretty self-explanatory. Our example,
private static final Integer ONE_MILLION = 1_000_000;
shows that the benefit is visual. Developers can quickly look at the code to verify that values are as expected. Underscores can be used in places other than natural groupings locations, being ignored wherever they are placed. Underscores in numeric literals cannot begin or terminate a numeric literal, otherwise, you’re free to place them where you’d like. While not demonstrated here, binary literal support has also been added. In the same way that hex literals are prefixed by 0x or 0X, binary literals would be prefixed by 0b or 0B.
Strings in switch are also self-explanatory. The switch statement now also accepts String. In our example, we switch on String argument passed to the main method to determine what request was made. On a side note, this is purely a compiler implementation with an indication that JVM support for switching on String may be added at a later date.
Type inference is another easy-to-understand improvement. Now instead of our old code
List<Transaction> transactions = new ArrayList<Transaction>();
we can simply do
List<Transaction> transactions = new ArrayList<>();
since the type can be inferred. Probably won’t find anyone who would argue that it shouldn’t have been so since the introduction of generics, but it’s now here.
Multi-catch will turn out to be very nice for the conciseness of exception handling code. Too many times when wanting to actually do something based on the exception type thrown, until now we were forced to have multiple catch blocks all doing essentially the same thing. The new syntax is very clean and logical. Our example,
catch (AccountFrozenException | ComplianceViolationException | AccountClosedException e)
shows how easily it can be done.
Finally, the last demonstration of a Project Coin feature is the try with resources syntax and support for retrieving suppressed exceptions. A new interface has been introduced, AutoCloseable that has been applied to all the expected suspects including Input/OutputStreams, Readers/Writers, Channels, Sockets, Selectors and java.sql resources Statement, ResultSet and Connection. In my opinion, the syntax is not as natural as the multi-catch change was, not that I have an alternative in mind.
try ( PreparedStatement s = _conn.prepareStatement(sql); ResultSet rs = s.executeQuery(); ) { while (rs.next()) { //print the average daily balance results } } catch (SQLException e) { //handle exception, but no need for finally to close resources for (Throwable t : e.getSuppressed()) { System.out.println("Suppressed exception message is " + t.getMessage()); } }
First we see that we can include multiple resources in try with resources – very nice. We can even reference previously declared resources in the same block as we did with our PreparedStatement. We still handle our exception, but we don’t need to have a finally block just to close the resources. Notice too that there is a new method getSuppressed() on Throwable. This allows us to access any Exceptions that were thrown in trying to “autoclose” the declared resources. There can be at most one suppressed exception per resource declared. Note: if the resource initialization throws an exception, it would be handled in your declared catch block.
That’s it. Nothing earth-shattering but some simple enhancements that we can all begin using without too much trouble. Project Coin also includes a feature regarding varargs and compiler warnings. Essentially, it boils down to a new annotation (@SafeVarargs) that can be applied at the method declaration to allow developers to remove @SuppressWarnings(“varargs”) from their consuming code. This has been applied on all the key suspects within the JDK, but the same annotation is available to you in any of your genericized varags methods.
The Project Coin feature set as it is described online is inconsistent at best. Hopefully this will give you a solid summary of what you can use from the proposal in JDK 7.
Reference: Java 7 – Project Coin Feature Overview from our JCG partners at the Carfey Software Blog.