I have this code:
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.callTest();
}
public void callTest() {
GenericTest gt = new GenericTest<Date>(); // this line don't compile
gt.test(new Date());
}
class GenericTest<T extends Date & List> {
T x;
public void test(T y) {
System.out.println(x.toString());
}
}
}
I understand why new GenericTest<Date>()
doesn't compile, it is because Date doesn't implement List interface, but if I instantiate GenericTest gt = new GenericTest()
without generic, the whole code works, and I don't understand why. The method test expects (T y)
where T extends Date
and implements List
, but it works with gt.test(new Date())
.
When you instantiate like this:
GenericTest gt = new GenericTest()
you use the raw version of GenericTest
type. This means that T
type will be replaced with it's first bound (in your case, Date
). That's why the method contract of GenericTest#test()
has a Date
parameter, but not a List
one.
Note that every bound, except the first one, must be an interface. Only the first bound can be a class. The reason for this is that it's not possible to have types, which inherit from more that one super-class.
So, since only the first parameter is a class, you won't be able to switch the type-parameters and the following class definition will be invalid:
class GenericTest<T extends List & Date> { }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With