Java8类型的通用擦除方法签名和lambdas不起作用

时间:2017-03-23 11:50:58

标签: java generics lambda java-8

解释这个的最好方法是使用示例:

public class Cosmos<T> {
    public void says(Consumer<String> stringConsumer) {
        stringConsumer.accept("we can");
    }
}

我原以为这会起作用:

new Cosmos().says(s -> System.out.println(s.length()));

,这不起作用! Java8认为sObject

但是,如果我使用任何内容定义T ,它就会起作用:

new Cosmos<Void>().says(s -> System.out.println(s.length()));

方法签名如何与泛型类型相关?

1 个答案:

答案 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]);

可以无错误地编译,表明toArrayList的类型参数不相关(泛型类型系统的限制)。

同样,当您使用new Cosmos()时,结果是原始类型,并且在其上调用says将不使用泛型类型签名。但是您不需要指定实际类型:

new Cosmos<>().says(s -> System.out.println(s.length()));

将编译没有错误。