Weird generics issue
Does anyone know why the following code does not compile and during compilation I get incompatible types exception ?
public class Test<T> {
public static void main(String[] args)
{
// using Test<?> solves the compilation error
Test test = new Test();
// getting error incompatible types:
// found : java.lang.Object
// required: java.lang.Integer
Integer number = test.getDays().get(0);
}
private List<Integer> getDays() {
return new ArrayList<开发者_C百科;Integer>();
}
}
and why using Test with the unbounded wildcard solves this ? I'm using java version 1.6.0_12
I am interpreting the question as why doesn't test.getDays()
return List<Integer>
when the return type is not dependent on the type parameter, T
?
When you create a variable that is a raw reference to an instance of Test
the compiler drops all generics for access via that variable (for backwards compatibility).
Because test
doesn't have its type <T>
specified this also means that the <Integer>
for getDays
is discarded.
Slight difference from Adel's answer, but did you mean this?
public class Test<T> {
public static void main(String[] args)
{
Test<Integer> test = new Test<Integer>();
Integer number = test.getDays().get(0);
}
private List<T> getDays() {
return new ArrayList<T>();
}
}
Try this:
public class Test<T> {
public static void main(String[] args)
{
// using Test<?> solves the compilation error
Test<Integer> test = new Test<Integer>();
// getting error incompatible types:
// found : java.lang.Object
// required: java.lang.Integer
Integer number = test.getDays().get(0);
}
private List<Integer> getDays() {
return new ArrayList<Integer>();
}
}
I tried to compile it and I have the same issues. I don't think the OP wants an explanation on how to use generics. Try it for yourself ... the odd thing is that it "should" work, because the generic type T isn't being used at all, as the declaration of getDate states that it will return a reference to a List of Integers.
You could instantiate test like this:
Test<JFrame> test = new Test();
... and it compiles! (of course you can use any existing Type here ...) Odd thing ...
If you remove the generic declaration it also works (of course).
The compiler can't determine the actual type for Test since you specified it as generic and then used the raw type. Adding the ? wildcard make the compiler aware that the actual class can only be determined at runtime; it won't check the class type.
You can also solve the compilation by either making the Test class non-generic or by making getDays() return a List.
When you declare a variable or field as a raw type, all usages of that field or variable lose all generic information, not just the generic information related to the type variable dropped by the raw type. That means your call to test.getDays()
returned a List
rather than a List<Integer>
, even though Integer is unrelated to T.
精彩评论