Monday, August 29, 2011

One of new feature of JDK 7 is simplified varargs method invocation

As part of JDK 7, one of new feature is simplified varargs method invocation. With this change, when a user tries to invoke a varargs method with a non-reifiable varargs type, the compiler currently generates an unsafe operation warning.
But with this change, warning will be generate at method declaration instead of at method call. And this provides user with more specific location of warning.

Example :

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class VarArgTest {
// Warning location 1
static <T> void addToList(List<T> listObj, T... elements) {
for (T t : elements) {
listObj.add(t);
}
}
// Warning location 2
static void faultyMethod(List<String>... l) {
Object[] objectArray = l; // Valid
objectArray[0] = Arrays.asList(new Integer(42));
String s = l[0].get(0); // ClassCastException thrown here
}

public static void main(String[] args) {
List<String> stringListA = new ArrayList<String>();
List<String> stringListB = new ArrayList<String>();

VarArgTest.addToList(stringListA, "Seven", "Eight", "Nine");
VarArgTest.addToList(stringListA, "Ten", "Eleven", "Twelve");
List<List<String>> listOfStringLists = new ArrayList<List<String>>();
// Warning location 3
VarArgTest.addToList(listOfStringLists, stringListA, stringListB);
// Warning location 4
VarArgTest.faultyMethod(Arrays.asList("Hello!"), Arrays.asList("World!"));
}

}

When we compile above program with earlier version of JDK i.e. prior to JDK 7, compiler will generate warning at warning location 3 and 4.
And if we compile above program with JDK 7, compiler will generate warning at warning location 1, 2, 3 and 4.


With this change in JDK 7, warning for varargs method invocation will generate warnings at method declaration which is more specific location for warnings. And advantage for this is safely and significantly reduces the total number of warnings reported to and suppressed by programmers.

Note : Please provide your views.

Sunday, August 21, 2011

Usage of generics in comparable and comparator interface

Generics provides with type safety for parameters and catches type checking error at compile time instead of runtime.
Comparable interface is used when two instance of same object needs to compare and comparator interface is used if object that doesn't implement
comparable interface or to compare objects using different ordering. Generally, we call ordering done by comparable interface as natural ordering
and ordering done by comparator interface as unnatural ordering.

Comparable Interface :
If a class is implementing a comparable interface as in below example, it can compare any type of object rather than object of type class or before
comparison, we need to check type of object and then cast an object to that type and then perform comparison.
For e.g.
public class Employee implements Comparable {
String empName;
Integer empId;
Integer age;
public static void main(String[] args) {
Employee empOne = new Employee();
empOne.empName = "Raj";
empOne.empId = 1;
empOne.age = 45;
ComparableTest cmpOne = new ComparableTest();
cmpOne.name = "Raj";
cmpOne.age = 45;
if(empOne.compareTo(cmpOne) == 1) {
System.out.println("Equal Object");
} else {
System.out.println("Unequal Object");
}
}
@Override
public int compareTo(Object o) {
if(o instanceof Employee/*if this check is not perform then code will throw run time error*/ && this.age.equals(((Employee)o).age)) {
return 1;
}
return 0;
}
}
Now example using generics.
public class Employee implements Comparable&ltEmployee> {
String empName;
Integer empId;
Integer age;
public static void main(String[] args) {
Employee empOne = new Employee();
empOne.empName = "Raj";
empOne.empId = 1;
empOne.age = 45;
ComparableTest cmpOne = new ComparableTest();
cmpOne.name = "Raj";
cmpOne.age = 45;
if(empOne.compareTo(cmpOne) == 1) { //This line will throw coompile time error as now type checking perform for method
System.out.println("Equal Object");
} else {
System.out.println("Unequal Object");
}
}
@Override
public int compareTo(Employee o) {
if(this.age.equals(o.age)) {
return 1;
}
return 0;
}
}
Comparator Interface :
If a class is implementing a comparator interface, it can compare two objects of any type and this might throw an error at run time or we need to do
instance type check on object before doing comparison.
Instead of doing instance type check and perform comparison, we can use generics which provides type safety to code and performs compile time checking
and prevents runtime errors.
Example 1 :
import java.util.Comparator;
public class ComparatorTest implements Comparator {
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof String && o2 instanceof String /*If instanceof check won't perform, any type object can be passed which will throw error at runtime*/
&& ((String)o1).length() == ((String)o2).length()) {
return 1;
}
return 0;
}
}
Exampe 1 using generics:
//Now this class can compare only String type object.
import java.util.Comparator;
public class ComparatorTest implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
if(o1.length() == o2.length()) {
return 1;
}
return 0;
}
}
Example 2 using generics :
import java.util.Comparator;
public class ComparatorTest implements Comparator<T> {
@Override
public int compare(T o1, T o2) {
if(o1.equals(o2)) {
return 1;
}
return 0;
}
}
In example 2, user can define type of comparator at time of creation of comparator object and comparison is performed based on equals method of type class as shown in example.

Note : Please provide feedbacks and suggestions.

Saturday, August 13, 2011

Change in use of generic in new version of JDK

With new JDK, there is change in use of generics and this new improved type inference for generic instance creation makes code more cleaner. It also removes unnecessarily duplication of type parameter while using generics.
With this change, we need not to mention type parameter while creating type of object on both side of expression like :

List<String> objectList = new ArrayList<>(); // change which is in new JDK 7

Earlier, we use to mention type parameter on both side of expression like :

List<String> objectList = new ArrayList<String>(); // prior to JDK 7

Program example :

import java.util.ArrayList;
public class GenericTypeInference {
public static void main(String[] args) {
ArrayList<String> nameList = new ArrayList<>(); // with new JDK, need not to mention type parameter on both side of expression
nameList.add("Rev");
nameList.add("John");
nameList.add("Sean");
System.out.println("Name list size : " + nameList.size());
System.out.println("Name list in string : " + nameList.toString());
for (String name : nameList) {
System.out.println("Name from list : " + name);
}
}

}

This feature make code more cleaner and prevents unnecessary type parameter duplication.

Tuesday, August 2, 2011

In JDK 7, numeral representation get change and it looks awesome

Binary Integral Literals
In JDK7, there is new implementation of integral values and that too in biinary form. This implementation provides user with way of given integral values in binary form and JVM internally convert it into short, byte, int and long.
For e.g.
public class BinaryLiteral {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int i = 0b10101;
byte b = 0b1010111;
short s = 0b0101111111111111;
System.out.println("Value of i = " + i + ", Value of short = " + s + ", Value of byte = " + b);
}

}

In above program, there is no compilation error and it prints proper value as this representation of integral value is supported in new JDK.

Underscore in numeric literal
Earlier, user cannot assign numeric literals with separator and it is difficult to deal with long numerals as it cannot be break into small chunks like credit card number (it has 16 digit but if we represent in numeral, it is one chunk of 16 digit), Phone numbers, etc.
In latest JDK, underscore is used as digit separator with numeral integral so that long numerals can represent as {chunk of digit}_{remaining chunk of digit}. And during compilation, JVM parses it correctly.
For e.g.
int i = 123_345_234; //supported in new JDK, won't be possible with earlier versions
This provides better readability of numerals which are long.
For e.g.
public class IntegralTypeTest {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int i = 167_968;
float f = 67_9.89_0f;
System.out.println("Integer val = " + i + ", Float val = " + f);
System.out.println("Sum of two = " + (i + f));
}

}

This program successfully compiles and prints correct result with new JDK.
There are certain limitations on placing underscore in numeral literals :
  • At the beginning or end of a number, underscore cannot be placed
  • Adjacent to a decimal point in a floating point literal, underscore cannot be placed
  • Prior to an F or L suffix, underscore cannot be placed
  • In positions where a string of digits is expected, underscore cannot be placed
For e.g.
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