以下代码会导致未经检查的转换编译器警告 -
{
List<String> first = first((Class)Integer.class);
}
private <T> List<String> first(Class<T> clazz) { return null; }
但是,以下代码没有任何警告 -
{
List<String> second = second((Class)Integer.class);
}
private List<String> second(Class<?> clazz) { return null; }
总共有三个警告,前两个我期望,但第三个没有意义 -
$ javac Test1.java -Xlint
Test1.java:6: warning: [unchecked] unchecked conversion
found : java.lang.Class
required: java.lang.Class<T>
List<String> first = first((Class)Integer.class);
^
Test1.java:6: warning: [unchecked] unchecked method invocation: <T>first(java.lang.Class<T>) in Test1 is applied to (java.lang.Class)
List<String> first = first((Class)Integer.class);
^
Test1.java:6: warning: [unchecked] unchecked conversion
found : java.util.List
required: java.util.List<java.lang.String>
List<String> first = first((Class)Integer.class);
^
3 warnings
编译器版本 -
$ javac -version
javac 1.6.0_45
我的问题是,为什么会发生第三次编译警告?
答案 0 :(得分:3)
由于您使用预通用(原始)
传递参数first((Class)Integer.class)
而不是
first((Class<?>)Integer.class)
first
的返回类型降级为预通用List
而不是List<String>
,并且使用List
预期List<String>
会导致未经检查的转换警告。
Raw Types上的Java文档解释:
原始类型显示在遗留代码中,因为许多API类(例如Collections类)在JDK 5.0之前不是通用的。使用原始类型时,您基本上可以获得pre-generics行为 - Box会为您提供对象。 为了向后兼容,允许将参数化类型分配给其原始类型:
...
但是如果将原始类型分配给参数化类型,则会收到警告:
答案 1 :(得分:1)
我的猜测是,传入原始类型Class
(而不是Class<?>
或Class<Integer>
)会使签名中的<T>
无效first
方法,由于某种原因导致整个方法调用被视为原始调用。因此,它不仅会使<T>
无效,还会使返回类型中的<String>
无效。