Generics In Java

Generics:

Generics add stability to our code by making more of our bugs detectable at compile time.
Generics enable types to be parameters when defining classes, interfaces and methods.

Benefits of Generics:


  • Strong type check at compile time.
  • Elimination of casts
  • Enabling programmers to implement generic algorithms


Generic Types:
A generic type is a generic class or interface that is parameterized over types.

Generic Class:
          Class name<T1,T2,T3.....Tn>
          Type parameter section delimited by angle brackets<> follows the class name.
           Type parameters are T1,T2,T3....Tn
Example:
             public class Box<T>
               {
                   private T t;
                   public void set(T t){
                       this.t=t;
                      }
                }
Type variable can be any non-primitive type, it can be any class type, any interface type, any array or even
another type variable.

Invoking & Instantiating generic type:
To perform a generic type invocation, replace T with some concrete value such as Integer.

Example: Box<Integer> integerBox;

  •   Integer is type Argument 
  •   Integer will hold a reference to a box of Integer. 
It is similar to method invocation instead of passing an argument to a method we are passing type argument
Integer in this case
Example: Box<T> ---> T is type parameter
               Box<String>---> String is a type argument
An invocation of generic type called Parameterized type

Instantiating:
use new keyword, place<Integer> b/w class name and paranthesis 
        Box<Integer> integerBox=new Box<>();

Raw Types:
It is name of a generic class or interface without any type arguments.
Example:
            Box<Integer> box=new Box<Integer>(); ----> parameterized type
            Box box=new Box(); -----------------> raw type

Scenarios:
1. Assigning a parameterized type to its raw type is allowed.
Example:
                Box<String> stngBox=new Box<String>();-----> parameterized type
                Box rawBox=stngBox;
2.Assigning a raw type to a parameterized type, we get warning
Example:
              Box rawBox=new Box(); -----> raw type
              Box<Integer> intBox=rawBox;
3.Using raw type to invoke generic methods , we get warning
Example:
               Box<String> stngBox=new Box<String>();
               Box rawBox=stngBox; ------>raw type
                rawBox.set(10);------>generic method call 

Generic Methods:
  •  Generic methods introduce their own type parameters.here type parmater scope is limited to method.
  •  Static and non static generic methods are allowed.
  •  Generic class constructor are allowed.
Syntax: It includes a type parameter inside angle brackets and appears before methods return type.
Example:
               public static<k,v> boolean compare(pair<k,v>p1,pair<k,v> p2)
                 {
                  }

Bounded Type Parameters:

If we want to restrict types that can be used as type argument in a parametrized type.
Examples: If we have a method that can accept only instances of number or its subclasses.

To declare a bounded type parameter, list the type parameter's name followed by extends keyword ,followed by upper bound.
Example:   
               <U extends Number>

Sub-Typing:

  •    We can subtype a generic class or interface by extending or implementing it.
  •     The relationship b/w type parameters of one class and the type parameter of another are determined by extends and implents class.
Example:
              ArrayList<E> implements List<E>
              List<E> extends Collection<E>

Type Inference:
  • It is java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument.
  • The Inference algorithm determines types of arguments, it tries to find the most specific type that works with type argument.
Example:
              Map<String,Integer> map=new HashMap<>(); 
   from above for HashMap<> there is no <String, Integer> inference algorithm does it.

WildCards:

In generic code, question mark '?' called wildcard and it represents an unknown type.

Wild cards are used in:
  •  Type of a parameter
  •  Field or local variable
  •  Return type
Upper Bounded Wild Cards:

It is used to relax restrictions on a variable

Syntax: '?' followed by extends keyword, followed by its upper bound
Example:  List<? extends Number>

Difference between List<Number> & List<?extends Number>:

List<Number>: it is more restrictive than List<?extends Number> and it matches only Number.
List<? extends Number> it matches a list of Number or its sub-classes.

UnBounded WildCards:

It is specified using '?'
Example: List<?>

Scenario: 
              public static void printList(List<Object> list)
               {
                    for(Object elem: list)
                         s.o.p("elements="+elem);
                }

from above printList() method  has to print a list of any type but it fails to achieve
 It prints only list of object instances
It cannot print List<Integer>, List,String>,List<Double> because they are subtypes of List<Object>

To solve above problem use unbounded wildcards

  public static void printList(List<?> list)
               {
                    for(Object elem: list)
                         s.o.p("elements="+elem);
                }

from above we can print  a list of any type.

Lower Bounded Wild Cards:

It restricts a unknown type to be a specific type or a super type of that type.
Synatax: '?' followed by super keyword , followed by its lower bound
Example:<? super A>

Difference between List<Integer> & List<? super Integer>
List<Integer> It is more restrictive than List<?super Integer> and it matches only Integer.
List<? super Integer> matches a list of Integer or super type of Integer.
supertype of Integer such as Integer,Number and Object

Example:
          public static void addNumber(List<? super Integer> list)
                {
                 }
                







  



 









 







Comments

Popular posts from this blog

Apache Spark

Streams In Java8