解释这个的最好方法是使用示例:
public class Cosmos<T> {
public void says(Consumer<String> stringConsumer) {
stringConsumer.accept("we can");
}
}
我原以为这会起作用:
new Cosmos().says(s -> System.out.println(s.length()));
但否,这不起作用! Java8认为s
是Object
!
但是,如果我使用任何内容定义T
,它就会起作用:
new Cosmos<Void>().says(s -> System.out.println(s.length()));
方法签名如何与泛型类型相关?
答案 0 :(得分:8)
原始类型的整个概念是为了与前Generics代码兼容而引入的,因此,使用原始类型将有效地关闭Generics all < / em>使用此类型,通用签名是否与类型的声明类型参数相关。
这可以通过以下代码示例来说明,该示例在Java 5之前生成编译错误并继续产生编译错误:
ArrayList list = new ArrayList();
String[] str = list.toArray(new String[0]);
与通用代码
相反ArrayList<Number> list = new ArrayList<Number>();
String[] str = list.toArray(new String[0]);
可以无错误地编译,表明toArray
和List
的类型参数不相关(泛型类型系统的限制)。
同样,当您使用new Cosmos()
时,结果是原始类型,并且在其上调用says
将不使用泛型类型签名。但是您不需要指定实际类型:
new Cosmos<>().says(s -> System.out.println(s.length()));
将编译没有错误。