Java Generics in layman language

Why Generics, what were the issues?

So lets first discuss why we need Generics.

List integers = new ArrayList();
integers.add(1);
integers.add(2);
integers.add("three");
for(int i=0;i<list.size();i++) {
if(list.get(i) == (Integer)list.get(i)) {
System.out.println(2*(Integer)list.get(i));
} else {
System.out.println(1);
throw new IllegalArgumentException("Value is not integer");
}
}
public static void main(String[] args) {
Set data = new HashSet();
Set updatedData = getData(data);
}
public static Set getData(Set data) {
data.add(1);
data.add("Two");
data.add(new ArrayList<>());
return data;
}
List<Integer> integers = new ArrayList<>();
integers.add(1);
integers.add(2);
integers.add("three"); // compile time exception

Type Erasure

Generics have a special property called Type erasure which means all the extra information added using generics will be removed at compile time during byte code generation. It is also required for backward compatibility.

List<Integer> list1 = new ArrayList<>();List list2 = new ArrayList<>();

Generic class

A class is Generic if it declares 1 or more type parameters. The type parameter itself is not a data type but can act as a place holder for any other datatype.

public class GenericClass<T,E> {
private T key;
private E value;
}
GenericClass<Integer,Integer> integers = new GenericClass<>();
GenericClass<String,Integer> strings = new GenericClass<>();

Generic Interface

Same rules apply for the interface as well

public interface GenericInterface<T,E> {
T firstMethod();
E secondMethod();
}
public class SampleClass implements GenericInterface<Integer,String> {
@Override
public Integer firstMethod() {
return null;
}
@Override
public String secondMethod() {
return null;
}
}

Generic methods

In previous examples, we saw classes that are completely generic in nature, But we can have a specific generic method as well in non-generic class. We can define generic methods inside a non-generic class and the scope of the type variable is inside the method only.

public <T,E> void genericMethod(T key,E value) {
System.out.println(key);
System.out.println(value);
}
public static <T> Map<T,T> staticGenericMethod(T val1,T val2) {
Map<T,T> map = new HashMap<>();
map.put(val1,val2);
return map;
}
public <T> Map<T,T> staticGenericMethod(T val1,T val2) {
Map<T,T> map = new HashMap<>();
map.put(val1,val2);
return map;
}

Generic Constructor

Generic constructor follows the same rule as other methods. They can come inside a generic class or can be in any other class also.

public class ClassWithGenericConstructor<T> {
private T key;
private T value;
public ClassWithGenericConstructor(T key,T value) {
this.key = key;
this.value = value;
}
}
public class ClassWithGenericConstructor {
public <T> ClassWithGenericConstructor(T key,T value) {
System.out.println(key);
}
}

Generics in Array :

Generics and the way array works contradict each other. Array preserves their type-information means it will throw an error if we add different types of data into it and Generics use type erasure, which is contradictory So we cannot instantiate a generic array in Java.

public class GenericArray<T> {
// this one is fine
public T[] notYetInstantiatedArray;
// causes compiler error; Cannot create a generic array of T
public T[] array = new T[5];
}

WildCards

WildCards defines unknown data types in Generics, Using it with super and extends is used to restrict the types used in Generic class.

Collection<?> coll = new ArrayList<String>();
List<? extends Number> list = new ArrayList<Long>();
Pair<String,?> pair = new Pair<String,Integer>();

Unbounded

Unbounded in which we can add any data type.

Collection<?> coll = new ArrayList<String>();

Bounded

In bounded we restrict the data types using extends and super.

List<? extends Number> list = new ArrayList<Long>();
List<? super Integer> list = new ArrayList<Number>();

Limitations of Generics

  1. Static fields of parameterized type are not allowed
private static T member; //This is not allowed
  1. We cannot create an instance of type parameter directly
new  T();   // not allowed
  1. Not compatible with primitive types
List<int> ids = new ArrayList<>();    //Not allowed
  1. Generic Exception class is not allowed
public class GenericException<T> extends Exception {}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store