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