Reputation: 254
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())
.
Upvotes: 13
Views: 3997
Reputation: 159
The error is because there is stronger type checks at compile time with generic code, and in the given code parameterized type is used.
As mentioned in problem that the GenericTest gt = new GenericTest()
compiles and executes, then it is only because here toString() method is being invoked. If it would be some List interface method then there will be ClassCastException on execution. Let us say size().
class GenericTest<T extends Date & List> {
public void test(T y) {
System.out.println(y.size()); // ClassCastException
}
}
Upvotes: 0
Reputation: 62874
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> { }
Upvotes: 17
Reputation: 136112
If you create a generic class instance without generic parameters the compiler gives a warning and does not control usage of the created instance any more. As to why the code works without declaring generic type - because in this case T is assumed to be Object, that is any type is good
Upvotes: -1