Why do we need Type Inference from Java 7?
http://www.coolcoder.in/2011/08/why-do-we-need-type-inference-from-java.html
Every good programmer likes to write a concise but effective and optimized code. Type Inference is a way introduced in JDK 7 which will surely give you benefits of less typing. Its been a long time that you have using the java code in following manner.
List<string> names = new ArrayList<string>(); Map<string, Object> objectMap = new HashMap<string, Object>();
But have you ever thought of code duplication while initializing the specific implementation of Collections? Why there is a need to write the parameters two times during an intialization?
Now most of you would be thinking of initializing as a raw types as you had been doing in previous JDK version.
Something like this.
List<string> names = new ArrayList(); Map<string, object=""> objectMap = new HashMap();
So whats new in JDK 7? What benefits you will have from the new feature?
So first we need to understand the difference between raw type and generic type intialization.
A statements like this ensures that the implementation will contain the same parameter as specified during initialization.
List<string> names = new ArrayList<string>();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
Diamond Operator
Okay Now I will introduce the new feature of JDK 7.
So we have something called Diamond operator in JDK 7 which reduces your extra typing while initialization.
Syntax:
List<string> names = new ArrayList<>();
So it not only reduces your code but also ensures the type checking.
Here is a more clear example explaining the benefits of type inference.
Advanced Example:
class Demo {
void printStudentNames(List<string> names) {
for(String name:names) {
System.out.println("String name:"+name);
}
}
public static void main(String[] args) {
Demo demo = new Demo();
demo.printStudentNames(new ArrayList<>()); // It saved typing here in a method call too.
List<string> names = new ArrayList<>();
printStudentNames(names);
List<string> copyOfNames = new ArrayList<>(names); // It saved typing here in a copy contructor invocation too.
}
}
Now what are its limitations?
It won't work in the case you use wildcards.
Something like this
Class Tree<t> {
public void demoFunction(List<t> objList) {
List<t> copyOfNames = new ArrayList<t>(objList); //This is not gonna work.
}
}
In the above case the arguments passed in the copy constructor should be Collection<? extends T>
So it wont accept the above inference type.
Feel free to write your reviews about the post in comments. And I will love to reply of doubts on the same.
Submit this post on reddit





Nice blog!
ReplyDeleteIs there an email address I can contact you in private?
of course I ment: List<String> list - it got stripped off.
ReplyDeleteYou did not get my point - try exactly this code:
ReplyDeleteList<String> = new ArrayList();
list.add(new Intger(9));
and you will get a compiler error because of type mismatch - the compiler will not let you add an Integer to this collection.
Anonymous,
ReplyDeleteYes the compiler will give an error if something like this written.
List<String> list = new ArrayList();.
list.add(new Integer(9));
But It should have been this as you have written in your comment.
List list = new ArrayList();.
list.add(new Integer(9));
So now whatever you add in list in not going to give you error. But in a objectList(generic) like this.
List<Object> list = new ArrayList();.
list.add(new Integer(9));
will give compilation error.
I would like to give one more example.
void appendNewObject(List<Object> list) {
list.add(new Object());.
}
Generics in Java are invariant. A List<String> is not a List<Object>, so the following would generate a compiler warning:
List<String> names = new ArrayList<String>();.
appendNewObject(names); // compilation error!
If you had declared appendNewObject to take a raw type List as parameter, then this would compile, and you'd therefore lose the type safety that you get from generics.
The diamond operator is required from what I understand:
ReplyDeleteList list = new ArrayList<>();
I will continue to use Guava instead.
ReplyDeleteList names = Lists.newArrayList("bob", fred");
...and many many more useful constructs.