The TechGuy

August 9, 2011

Java 7 – Language Enhancements (Part 1)

Filed under: Framework/APIs,Java — Zeeshan Bilal @ 12:02 PM

After nearly five year (on July 2011), Java SE 7 has been released! With Project Coin, the new Fork/Framework, the New File System API (NIO.2), and more. Java SE 7 is an important step in Java’s evolution. There are number of enhancements in the programming language, listed below.

  • Binary Literals
  • Underscores in Numeric Literals
  • Strings in switch Statements
  • Type Inference for Generic Instance Creation
  • Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods
  • The try-with-resources Statement
  • Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking

Binary Literals

In Java SE 7, the integral types (byteshortint, and long) can also be expressed using the binary number system. To specify a binary literal, add the prefix 0b or 0B to the number. Declarative uses of binary literals are demonstrated below:

An 8-bit byte value:


byte
ab = (byte)0b00100001;

An 16-bit short value:


short
as = (short)0b1010000101000101;

Few 32-bit int values:


int
ai = 0b10100001010001011010000101000101;
int ai2 = 0B101; // The B can be upper or lower case.

An 64-bit long value. Note the L suffix:


long
al = 0b1010000101000101101000010100010110100001010001011010000101000101L;

Binary literals can make relationships among data more apparent than they would be in hexadecimal or octal. For example, each successive number in the following array is rotated by one bit:


public static final int
[] phases = {
   0b00110001,
   0b01100010,
   0b11000100,
   0b10001001,
   0b00010011,
   0b00100110,
   0b01001100,
   0b10011000
}

In hexadecimal, the relationship among the numbers is not readily apparent:


public static final int
[] phases = {
   0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98
}

You can use binary literals to make a bitmap more readable:


public static final short
[] HAPPY_FACE = {
   (short)0b0000011111100000;
(
short)0b0000100000010000;
(
short)0b0001000000001000;
(
short)0b0010000000000100;
(
short)0b0100000000000010;
(
short)0b1000011001100001;
(
short)0b1000011001100001;
(
short)0b1000000000000001;
(
short)0b1000000000000001;
(
short)0b1001000000001001;
(
short)0b1000100000010001;
(
short)0b0100011111100010;
(
short)0b0010000000000100;
(
short)0b0001000000001000;
(
short)0b0000100000010000;
(
short)0b0000011111100000;
}

Uses of binary literals in bit wise operations also help to understand the logic and program structure.

Underscores in Numeric Literals

Any number of underscore characters (_) can appear anywhere between digits in a numerical literal. This feature enables you, for example, to separate groups of digits in numeric literals, which can improve the readability of your code. For instance, if your code contains numbers with many digits, you can use an underscore character to separate digits in groups of three, similar to how you would use a punctuation mark like a comma, or a space, as a separator. The following example shows other ways you can use the underscore in numeric literals:


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 = (byte)0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;

You can place underscores only between digits; you cannot place underscores in the following places:

  • At the beginning or end of a number
  • Adjacent to a decimal point in a floating point literal
  • Prior to an F or L suffix
  • In positions where a string of digits is expected

The following examples demonstrate valid and invalid underscore placements (which are highlighted) in numeric literals:


float
pi1 = 3_.1415F;
// Invalid; cannot put underscores adjacent to a decimal point
float pi2 = 3._1415F; // Invalid; cannot put underscores adjacent to a decimal point
long socialSecurityNumber1 = 999_99_9999_L; // Invalid; cannot put underscores prior to an L suffix
int x1 = _52; // This is an identifier, not a numeric literal
int x2 = 5_2; // OK (decimal literal)
int x3 = 52_; // Invalid; cannot put underscores at the end of a literal
int x4 = 5_______2; // OK (decimal literal)
int x5 = 0_x52; // Invalid; cannot put underscores in the 0x radix prefix
int x6 = 0x_52; // Invalid; cannot put underscores at the beginning of a number
int x7 = 0x5_2; // OK (hexadecimal literal)
int x8 = 0x52_; // Invalid; cannot put underscores at the end of a number
int x9 = 0_52; // OK (octal literal)
int x10 = 05_2; // OK (octal literal)
int x11 = 052_; // Invalid; cannot put underscores at the end of a number

Strings in switch Statements

You can use the String class in the expression of a switch
statement.


public
String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) {
String typeOfDay;
switch (dayOfWeekArg) {
case “Monday”:
typeOfDay = “Start of work week”;
break;
case “Tuesday”:
case “Wednesday”:
case “Thursday“:
typeOfDay = “Midweek”;
break;
case “Friday”:
typeOfDay = “End of work week”;
break;
case “Saturday”:
case “Sunday”:
typeOfDay = “Weekend”;
break;
default:
throw new IllegalArgumentException(“Invalid day of the week: “ + dayOfWeekArg);
}
return typeOfDay;
}

The switch statement compares the String object in its expression with the expressions associated with each case label as if it were using the String.equals method; consequently, the comparison of String objects in switch statements is case sensitive. The Java compiler generates generally more efficient bytecode from switch statements that use String objects than from chained if-else-then statements.

Type Inference for Generic Instance Creation

You can replace the type arguments required to invoke the constructor of a generic class with an empty set of type parameters (<>) as long as the compiler can infer the type arguments from the context. This pair of angle brackets is informally called the diamond. For example, consider the following variable declaration:


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

In Java SE 7, you can substitute the parameterized type of the constructor with an empty set of type parameters (<>):


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

Note that to take advantage of automatic type inference during generic class instantiation, you must specify the diamond. In the following example, the compiler generates an unchecked conversion warning because the HashMap() constructor refers to the HashMap raw type, not the Map<String, List<String>> type:


Map<String, List<String>> myMap = new HashMap(); // unchecked conversion warning

Java SE 7 supports limited type inference for generic instance creation; you can only use type inference if the parameterized type of the constructor is obvious from the context. For example, the following example does not compile:


List<String> list = new ArrayList<>();
list.add(“A”);
// The following statement should fail since addAll expects Collection<? extends String>
list.addAll(new ArrayList<>());

Note that the diamond often works in method calls; however, it is suggested that you use the diamond primarily for variable declarations.

In comparison, the following example compiles:


// The following statements compile:
List<? extends String> list2 = new ArrayList<>();
list.addAll(list2);

There are some other examples and uses of Type Interface of Generic Instance Creation that we will cover in our next part (Part 2) with remaining three language enhancements.

Advertisements

11 Comments

  1. very nice:)

    Comment by saira — August 11, 2011 @ 7:18 AM

  2. The most wanted feature was “Strings in switch Statements” in switch statement. We had to use Enum for this purpose but this feature will cater code complications. Underscores in Numeric Literals is a nice touch to increase readability. I’m sure there are more features in Java 7 which I would like you to add in this page. Keep up the good work!

    Comment by Hassan Khan (OCPJP 6.0) — August 11, 2011 @ 10:26 AM

  3. Very informative .

    Comment by Nouman — August 11, 2011 @ 10:48 AM

  4. Great article!

    Comment by Aftab NAqvi — August 12, 2011 @ 6:24 PM

  5. Thanks, Your comments are really honor for me.

    Comment by zishanbilal — August 12, 2011 @ 6:51 PM

  6. Great stuff, easy to understand and intuitive.

    Comment by ALost Byte — August 12, 2011 @ 8:26 PM

  7. and the string switch, thats just awesome.

    Comment by ALost Byte — August 12, 2011 @ 8:28 PM

  8. the switch statement with string is really helpful.

    if you need case insensitive switch you can use

    String key=”Pakistan”;
    switch(key.toLowerCase()){
    case “pakistan”:

    break;
    }

    Comment by Abduliam Rehmanius (@abduliam) — August 12, 2011 @ 8:47 PM

  9. Great article. Your articles are easy to understand and provide to the point information. Thanks.

    Comment by AR — August 12, 2011 @ 8:50 PM

  10. WONDERFUL Post.thanks for share..more wait .. …

    Comment by Rex Ryan — August 15, 2011 @ 12:57 AM

  11. Great article very informative and very good example to understand Thanks.

    Comment by ibtesam — August 16, 2011 @ 10:52 AM


RSS feed for comments on this post.

Blog at WordPress.com.