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?
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 T
s 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.