Java - Generic Methods and Constructors

Introduction

You can define type parameters in a method declaration.

They are specified in angle brackets before the return type.

The type that contains the generic method declaration does not have to be a generic type.

The following copy method is a method with generic type.

public static <T> void copy(Wrapper<T> source, Wrapper<? super T> dest){
    T value = source.get();
    dest.set(value);
}

Specify the generic type for a generic method

Usually, you do not need to specify the actual type parameter.

The compiler figures it out for you using the value you pass to the method.

To pass the actual type parameter for the method's formal type parameter, specify it in angle brackets < > between the dot and the method name in the method call

Main.<String>copy(stringWrapper, objectWrapper); 

Main.copy(stringWrapper, objectWrapper); //OK

Demo

public class Main {
  public static void main(String[] args) {
    Wrapper<Object> objectWrapper = new Wrapper<Object>(new Object());
    Wrapper<String> stringWrapper = new Wrapper<String>("Hello");
    Main.<String>copy(stringWrapper, objectWrapper); 
    System.out.println(objectWrapper.get());
  }//w  ww. ja  v a2 s . co  m
  public static <T> void copy(Wrapper<T> source, Wrapper<? super T> dest){
    T value = source.get();
    dest.set(value);
  }

}

class Wrapper<T> {
  private T ref;

  public Wrapper(T ref) {
    this.ref = ref;
  }

  public T get() {
    return ref;
  }

  public void set(T a) {
    this.ref = a;
  }
}

Result

Define type parameters for constructors

The following code defines a type parameter U for the constructor of class Test.

It places a constraint for U.

class Test<T> {
   public <U extends T> Test(U k) {
           // Do something
   }
}

The compiler can figure out the actual type parameter passed to the constructor.

If you want to specify the actual type, specify it in angle brackets between the new operator and the name of the constructor.

Test<Number> t1 = new <Double>Test<Number>(new Double(1.9));

Let the compiler figure out that we are using Integer as the actual type parameter for the constructor

Test<Number> t2 = new Test<Number>(new Integer(123));