Difference between revisions of "Generics"
(Created page with "Java Genrics is one of the most important feature introduced in Java 5. If you have been working on Java Collections and with version 5 or higher, I am sure that you have used...") |
|||
Line 92: | Line 92: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | Notice the use of GenericsType class in the main method. We don’t need to do type-casting and we can remove ClassCastException at runtime. If we don’t provide the type at the time of creation, compiler will produce a warning that “GenericsType is a raw type. References to generic type GenericsType<T> should be parameterized”. When we don’t provide type, the type becomes Object and hence it’s allowing both String and Integer objects but we should always try to avoid this because we will have to use type casting while working on raw type that can produce runtime errors. | ||
+ | |||
+ | '''Tip''': We can use @SuppressWarnings("rawtypes") annotation to suppress the compiler warning, check out java annotations tutorial. | ||
+ | |||
+ | Also notice that it supports java [[autoboxing]]. | ||
+ | |||
+ | ==Java Generic Interface== | ||
+ | Comparable interface is a great example of Generics in interfaces and it’s written as: | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | |||
+ | package java.lang; | ||
+ | import java.util.*; | ||
+ | |||
+ | public interface Comparable<T> { | ||
+ | public int compareTo(T o); | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | In similar way, we can create generic interfaces in java. We can also have multiple type parameters as in Map interface. Again we can provide parameterized value to a parameterized type also, for example new HashMap<String, List<String>>(); is valid. |
Revision as of 09:38, 1 August 2018
Java Genrics is one of the most important feature introduced in Java 5. If you have been working on Java Collections and with version 5 or higher, I am sure that you have used it. Generics in Java with collection classes is very easy but it provides a lot more features than just creating the type of collection and we will try to learn features of generics in this article. Understanding generics can become confusing sometimes if we go with jargon words, so I would try to keep it simple and easy to understand.
Generics in Java
Generics was added in Java 5 to provide compile-time type checking and removing risk of ClassCastException that was common while working with collection classes. The whole collection framework was re-written to use generics for type-safety. Let’s see how generics help us using collection classes safely.
List list = new ArrayList();
list.add("abc");
list.add(new Integer(5)); //OK
for(Object obj : list){
//type casting leading to ClassCastException at runtime
String str=(String) obj;
}
Above code compiles fine but throws ClassCastException at runtime because we are trying to cast Object in the list to String whereas one of the element is of type Integer. After Java 5, we use collection classes like below.
List<String> list1 = new ArrayList<String>(); // java 7 ? List<String> list1 = new ArrayList<>();
list1.add("abc");
//list1.add(new Integer(5)); //compiler error
for(String str : list1){
//no type casting needed, avoids ClassCastException
}
Notice that at the time of list creation, we have specified that the type of elements in the list will be String. So if we try to add any other type of object in the list, the program will throw compile time error. Also notice that in for loop, we don’t need type casting of the element in the list, hence removing the ClassCastException at runtime.
Java Generic Class
We can define our own classes with generics type. A generic type is a class or interface that is parameterized over types. We use angle brackets (<>) to specify the type parameter.
To understand the benefit, lets say we have a simple class as:
package com.journaldev.generics;
public class GenericsTypeOld {
private Object t;
public Object get() {
return t;
}
public void set(Object t) {
this.t = t;
}
public static void main(String args[]){
GenericsTypeOld type = new GenericsTypeOld();
type.set("Pankaj");
String str = (String) type.get(); //type casting, error prone and can cause ClassCastException
}
}
Notice that while using this class, we have to use type casting and it can produce ClassCastException at runtime. Now we will use java generic class to rewrite the same class as shown below.
package com.journaldev.generics;
public class GenericsType<T> {
private T t;
public T get(){
return this.t;
}
public void set(T t1){
this.t=t1;
}
public static void main(String args[]){
GenericsType<String> type = new GenericsType<>();
type.set("Pankaj"); //valid
GenericsType type1 = new GenericsType(); //raw type
type1.set("Pankaj"); //valid
type1.set(10); //valid and autoboxing support
}
}
Notice the use of GenericsType class in the main method. We don’t need to do type-casting and we can remove ClassCastException at runtime. If we don’t provide the type at the time of creation, compiler will produce a warning that “GenericsType is a raw type. References to generic type GenericsType<T> should be parameterized”. When we don’t provide type, the type becomes Object and hence it’s allowing both String and Integer objects but we should always try to avoid this because we will have to use type casting while working on raw type that can produce runtime errors.
Tip: We can use @SuppressWarnings("rawtypes") annotation to suppress the compiler warning, check out java annotations tutorial.
Also notice that it supports java autoboxing.
Java Generic Interface
Comparable interface is a great example of Generics in interfaces and it’s written as:
package java.lang;
import java.util.*;
public interface Comparable<T> {
public int compareTo(T o);
}
In similar way, we can create generic interfaces in java. We can also have multiple type parameters as in Map interface. Again we can provide parameterized value to a parameterized type also, for example new HashMap<String, List<String>>(); is valid.