User Tools

Site Tools


java_generics

Java Generics

Java generics help when you want to reuse code. Suppose you write a method that prints out the output of an object using the method toString()

class Fish {}
 
 
public class PrintMe { 
    void printOut(Fish fish){
        System.out.println(fish.toString());
    }
}

If instead of a Fish we wanted to print a Bird we'd be forced to overload printOut to accept a Bird. An option would be to write

void printOut(Object anObject){
    System.out.println(anObject.toString());
}

However, one is forced to do a lot of castings because this method really accepts only Objects not any object that inherits from it

printOut((Object) fish)

Generics turn helpful in this occasion:

public class PrintMe<T>{
    void <S> printOut(S in){
        System.out.println(in.toString());
    }
}

Here we tell Java that there are two generic types T and S and that we are going to use it in the class PrintMe and in the method printOut.

Limitations

The main problems come from type erasure. In practice the compiler does the castings in the background and creates a generic class or method as if it would handle Objects. So, with generics you can't

  1. Instantiate a generic type
  2. Create an array of that static type
  3. call instanceof on a generic type. For Java List<String> or List<Integer> are the same!!!
  4. Use primitive types as generic type, because they need to be upcast to Object. Use wrappers instead.
  5. Create a static variable as generic type parameter

Static properties are not allowed because Java does not know until runtime the exact type. In practice it would know it only when you instantiate a generic class! In Java the compiler does this trick of casting the generic type to an Object and therefore it looses control of it. In C++ instead, the compiler creates a number of real classes with the appropriate generic type. If Java would work as C++ static types would be allowed.

Wildcards

Wildcards are used in the case one wants to limit the types allowed by a generic method/class.

Unbound wildcards

List<?> list = new ArrayList<String>();

Creates an instance of a List of any kind. An ArrayList of String> will be ok, for instance.

Upper-bound wildcards

Upper bound wildcards are used when you want to accept an instance of a class or any of its derivatives

List<? extends Exception> list = new ArrayList<IOException>();

Lower-bound wildcards

java_generics.txt · Last modified: 2017/01/02 16:17 by 178.237.8.52