Generics
		
		
		
			
				- Type parameters are used to declare the return type, parameter types and local variable types
 
				- When the compiler translates generic method into bytecodes, it removes the ytpe parameter section and replaces the type parameters with actual types
 
				- By default all generic types are replaced with type Object
 
				- A Java compiler applies strong type checking to generic code and issues errors if the code violates type safety
 
				- Restrictions
					
						- Cannot Instantiate Generic Types with Primitive Types
 
						- Cannot Create Instances of Type Parameters
 
						- Cannot Declare Static Fields Whose Types are Type Parameters
 
						- Cannot Use Casts or instanceof With Parameterized Types
 
						- Cannot Create Arrays of Parameterized Types
 
						- Cannot Create, Catch, or Throw Objects of Parameterized Types
 
						- Cannot Overload a Method Where the Formal Parameter Types of Each Overload Erase to the Same Raw Type
 
					
				 
			
		 
		Type Parameter Naming Conventions
		
			
				- E - Element (used extensively by the Java Collections Framework)
 
				- K - Key
 
				- N - Number
 
				- T - Type
 
				- V - Value
 
				- S,U,V etc. - 2nd, 3rd, 4th types
 
			
		 
		Type Casting
		
			
				- Object o = new A()
 
				- ((A)o).functionDefinedInA()
 
			
		 
		
			
public class Box
{
	private Object obj;
	public Box(Object o)
	{
		obj = o;
	}
	public Object getObj()
	{
		return obj;
	}
}
			
			
public class G
{
	public static void main(String args[])
	{
		Box b = new Box("Hello World!");
		String a = (String)b.getObj();//type casting
		System.out.println(a.toLowerCase());
	}
}
			
		 
		Generic Class
		
			
public class Box<T>
{
	private T obj;
	public Box(T o)
	{
		obj = o;
	}
	public T getObj()
	{
		return obj;
	}
}
			
			
public class G
{
	public static void main(String args[])
	{
		Box<String> b = new Box<String>("Hello World!");
		String a = b.getObj();
		System.out.println(a.toLowerCase());
	}
}
			
		 
		Diamond
		
			
public class G
{
	public static void main(String args[])
	{
		Box<String> b = new Box<>("Hello World!");
		String a = b.getObj();
		System.out.println(a.toLowerCase());
	}
}
			
		 
		Multiple Types
		
			
public class Pair<T, S>
{
	private T name;
	private S age;
	public Pair(T n, S a)
	{
		name = n;
		age = a;
	}
	public T getName()
	{
		return name;
	}
	public S getAge()
	{
		return age;
	}
}
			
			
public class G
{
	public static void main(String args[])
	{
		Pair<String, Integer> p = new Pair<String, Integer>("Lin", 37);
		System.out.println(p.getName()+": "+p.getAge());
	}
}
			
		 
		Generic Method
		
			
public class G
{
	public static <T, S> boolean compare(Pair<T, S> p1, Pair<T, S> p2)
	{
		if(p1.getName().equals(p2.getName()) && p1.getAge().equals(p2.getAge()))
			return true;
		else
			return false;
	}
	public static void main(String args[])
	{
		Pair<String, Integer> p = new Pair<String, Integer>("Lin", 37);
		Pair<String, Integer> p2 = new Pair<String, Integer>("Lin", 38);
		Systemystem.out.println(G.<String, Integer>compare(p, p2));
		System.out.println(compare(p, p2));//type interface
	}
}
			
		 
		Bounded Type Parameters
		
			
				- Restrict the types that can be used as type arguments in a parameterized type
 
			
		 
		
			
public class Box<T extends Number>
{
	private T obj;
	public Box(T o)
	{
		obj = o;
	}
	public T getObj()
	{
		return obj;
	}
}
			
			
public class G
{
	public static void main(String args[])
	{
		Box<Integer> b = new Box<Integer>(100);
		//Box<String> b = new Box<String>("Hello World!");//compile erro
		System.out.println(b.getObj());
	}
}
			
		 
		Wildcard
		
			
				- Use ? as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific)
 
				- The wildcard is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype
 
			
		 
		
			
				- The term List is more restrictive than List<? extends Number> because the former matches a list of type Number only, whereas the latter matches a list of type Number or any of its subclasses
 
			
			
import java.util.*;
public class G
{
	public static double sumOfList(List<? extends Number> list) {
		double s = 0.0;
	    	for (Number n : list)
			s += n.doubleValue();
	    	return s;
	}
	public static void main(String args[])
	{
		List<Integer> li = Arrays.asList(1, 2, 3);
		System.out.println("sum = " + sumOfList(li));
	}
}
			
		 
		Generic Array
		
			
import java.util.*;
public class temp
{
	public static void main(String args[])
	{
		List[] l2 = new List<?>[2];
		l2[0] = new ArrayList<Integer>();
		l2[1] = new ArrayList<Integer>();
		l2[0].add(1);
		l2[0].add(2);
		Object [] array = l2[0].toArray();
		for(Object e : array)
			System.out.println(e);
	}
}
			
		 
		Reference