Generics – Implementation in Java Spring Boot and Angular (part-1)

Basic:
Generics is used to work with different data types and to make the code resealable. Generics can be used in function,interface and class.
Generics forces compiler to write type safe code so that we don’t get run time error and if there is an error it can be detected at compile time.
When to use Generics?
1. When your function, interface or class will work with a variety of data types (different data types)
2. When your function, interface or class uses that data type in several places (re-usability)

Angular works with typescript, we will use some example with typescript.
Later, we also will show example with Java.

For example, you have function which accept a number as an argument and return the same number.

function identity(arg: number): number {
return arg;
}

Now, if we want to receive any type to argument and we can use generics.

function identity<T>(arg: T): T {
return arg;
} 

Here,
<T> – means that identity function will accept a generic type data. It is a style of declaring generics into a function,interface or class. T is just a letter just like a variable name. You can use any letter.
(arg: T) – This function will have a generic type as argument
: T – This means the function will return a generic type.

If we want to accept more than one generic type. Below function will receive 2 generic type data.

function identities<T, U>(arg1: T, arg2: U): T {
   return arg1;
}

Now, if we call like
identities(1,”2″);
identities(“string”,2);


Generic interface

interface Identities<V, W> {
   id1: V,
   id2: W
}

This interface uses two generic datatype.
Now ,lets implement this interface into a function.

function identities<T, U> (arg1: T, arg2: U): Identities<T, U> {
   console.log(arg1 + ": " + typeof (arg1));
   console.log(arg2 + ": " + typeof (arg2));
   let identities: Identities<T, U> = {
    id1: arg1,
    id2: arg2
  };
  return identities;
}

Now, the compiler will force you to use these two type.
identities<T, U> – means this function will accept two generic type data; this is the declaration part to use generics.
(arg1: T, arg2: U) – means, this function will accept two generic argument
: Identities<T, U> – means, this function will return a object which will have exactly two property as defined in the interface where the are generic type of T and U respectively.

Generics constraints
Sometimes we can restrict which type we accept as generic type putting a constraint.
For example, below identity function accept a generic type T which must have a property named length.

interface Length {
    length: number;
}

function identity<T extends Length>(arg: T): T {
   // length property can now be called
   console.log(arg.length);
   return arg;

Now the compiler will let us know at compile time when we call the function with a type that does not support .length.
 
Another excellent example is when we pass a object and it’s key as argument. At compile time, we can check whether that object contain’s that key.

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
    return obj[key];
}

Here, getProperty function makes sure that key of that object exists so that we don’t get runtime error. This called type safe coding.

JAVA :
Below is the example of a Generics class.

class Student<T>{
   T age;
   Student(T age){
      this.age = age;
   }
   public void display() {
      System.out.println("Value: "+this.age);
   }
}
public class GenericsExample {
   public static void main(String args[]) {
      Student<Float> std1 = new Student<Float>(25.5f);
      std1.display();
      Student<String> std2 = new Student<String>("25");
      std2.display();
      Student<Integer> std3 = new Student<Integer>(25);
      std3.display();
   }
}

Output:
Value: 25.5
Value: 25
Value: 25

Instead of the typed parameter in generics (T) you can also use “?”, representing an unknown type. 
Java provides 3 types of wild cards namely upper-bounded, lower-bounded, un-bounded.

Upper-bounded :
For example, say you want to write a method that works on List < integer >, List < double >, and List < number > , you can do this  using an upper bounded wildcard.
To declare an upper-bounded wildcard, use the wildcard character (‘?’), followed by the extends keyword, followed by its upper bound.
<? extends T> represent a upper-bound willcards which will accept only T or subclass.

class WildcardDemo 
{ 
    public static void main(String[] args) 
    { 
          
        //Upper Bounded Integer List 
        List<Integer> list1= Arrays.asList(4,5,6,7); 
          
        //printing the sum of elements in list 
        System.out.println("Total sum is:"+sum(list1)); 
  
        //Double list 
        List<Double> list2=Arrays.asList(4.1,5.1,6.1); 
          
        //printing the sum of elements in list 
        System.out.print("Total sum is:"+sum(list2)); 
    } 
  
    private static double sum(List<? extends Number> list)  
    { 
        double sum=0.0; 
        for (Number i: list) 
        { 
            sum+=i.doubleValue(); 
        } 
  
        return sum; 
    } 
} 

In the above program, list1 and list2 are objects of the List class. list1 is a collection of Integer and list2 is a collection of Double. Both of them are being passed to method sum which has a wildcard that extends Number. This means that list being passed can be of any field or subclass of that field. Here, Integer and Double are subclasses of class Number.

If you pass a collection object other than type that is subclass of Number as a parameter to the sum() of the above program a compile time error will be generated.

     List<String> list3=Arrays.asList("dfd","sfsdf");
      list3.add("Raju");
      list3.add("Ramu");

      sum(list3);

Compile time error
:


Lower-bounded :
It is expressed using the wildcard character (‘?’), followed by the super keyword, followed by its lower bound: <? super A>
It will accept only T or super class.

class WildcardDemo 
{ 
    public static void main(String[] args) 
    { 
        //Lower Bounded Integer List 
        List<Integer> list1= Arrays.asList(4,5,6,7); 
          
        //Integer list object is being passed 
        printOnlyIntegerClassorSuperClass(list1); 
  
        //Number list 
        List<Number> list2= Arrays.asList(4,5,6,7); 
          
        //Integer list object is being passed 
        printOnlyIntegerClassorSuperClass(list2); 
    } 
  
    public static void printOnlyIntegerClassorSuperClass(List<? super Integer> list) 
    { 
        System.out.println(list); 
    } 
} 

Here arguments can be Integer or superclass of Integer(which is Number). The method printOnlyIntegerClassorSuperClass will only take Integer or its superclass objects. However if we pass list of type Double then we will get compilation error. It is because only the Integer field or its superclass can be passed . Double is not the superclass of Integer.

Use extend wildcard when you want to get values out of a structure and super wildcard when you put values in a structure. Don’t use wildcard when you get and put values in a structure.
Note: You can specify an upper bound for a wildcard, or you can specify a lower bound, but you cannot specify both.

Un-bounded :
This wildcard type is specified using the wildcard character (?), for example, List. This is called a list of unknown type. 
For example, if want to accept an ArrayList of object type as a parameter, you just need to declare an unbounded wildcard.

class unboundedwildcardemo 
{ 
    public static void main(String[] args)  
    { 
  
        //Integer List 
        List<Integer> list1= Arrays.asList(1,2,3); 
  
        //Double list 
        List<Double> list2=Arrays.asList(1.1,2.2,3.3); 
  
        printlist(list1); 
  
        printlist(list2); 
    } 
  
    private static void printlist(List<?> list)  
    { 
  
        System.out.println(list); 
    } 
} 

In the 2nd part, we will see a real implementation in angular project.







Ref:
1. https://www.geeksforgeeks.org/wildcards-in-java/
2. https://medium.com/@rossbulat/typescript-generics-explained-15c6493b510f

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s