Tony Tony - 2 months ago 12
Java Question

Static generic methods

Can you explain why the following works?

public class GenericsTest<T> {

public void doSomething(T v1, T v2) {

}

public static <T> void doSomethingStatic(T v1, T v2) {

}

public static <T> void doSomethingStaticList(List<T> v1, List<T> v2)
{

}

public static void main(String[] args) {
GenericsTest<String> gt = new GenericsTest<>();

// OK
gt.doSomething("abc", "abc");

// Not OK
gt.doSomething(1, "abc");

// OK
doSomethingStatic(1, 2);

// Still OK
doSomethingStatic(1, "abc");

// So why is this not OK?
List<String> list1=new LinkedList<>();
List<Integer> list2=new LinkedList<>();
doSomethingStaticList(list1,list2);
}
}


T v1, T v2
should be the same type in
doSomethingStatic
, but I'm still able to pass different types(integer and string).

If
doSomethingStatic()
takes a common super class by default, why doesn't
doSomethingStaticList()
work with different types?

Answer

In non-static case you define T as String when you create instance of GenericsTest. Hence passing an int will give compile error. If you did gt.doSomething(1, 2) it would fail as well.

In static case, you don't define T manually, it is derived from parameters. It will be the first common superclass of both classes - which in this case is Object. You might want to use bounded wildcard, e.g. <T extends Number> or <T extends CharSequence>.

Note that you have two different Ts here:

  • GenericsTest<T>
  • public static <T> void doSomethingStatic(T v1, T v2)

The declaration of generic parameter is whenever you write <T>. You can use different letters in this case to avoid confusion.