Java &引用;“不兼容类型”;lambda/方法引用和泛型的编译器错误
在处理一些旧代码时,我偶然发现了一个问题,用lambda表达式或方法引用替换了几个匿名类。这个问题有点难以用语言来解释,但我会尽我最大的努力,下面我还添加了一个简短的例子,用我的最大能力来说明我的问题 我的例子包括Java &引用;“不兼容类型”;lambda/方法引用和泛型的编译器错误,java,generics,lambda,compiler-errors,method-reference,Java,Generics,Lambda,Compiler Errors,Method Reference,在处理一些旧代码时,我偶然发现了一个问题,用lambda表达式或方法引用替换了几个匿名类。这个问题有点难以用语言来解释,但我会尽我最大的努力,下面我还添加了一个简短的例子,用我的最大能力来说明我的问题 我的例子包括 一个函数接口GenericListener,它接受一个类型参数V,并具有一个方法“genericCallback(V genericValue)” 一个类CallbackProducer,它接受一个类型参数T。这个类还有一个方法可以添加一个类型为Integer的GenericList
import javax.swing.*;
公共班机{
公共静态void main(最终字符串[]args){
调用器(Main::new);
}
公用干管(){
//编译器错误,未指定CallbackProducer的“T”类型
CallbackProducer1=新的CallbackProducer();
producer1.addIntegerListener(this::integerReceived);
//编译器错误,CallbackProducer没有菱形括号
新建CallbackProducer().addIntegerListener(this::integerReceived);
//此外,CallbackProducer上没有菱形括号的lambdas的编译器错误
新建CallbackProducer().addIntegerListener(intValue->integerReceived(intValue));
//之所以有效,是因为为CallbackProducer的“T”指定了(任意)类型
CallbackProducer2=新的CallbackProducer();
producer2.addIntegerListener(this::integerReceived);
//因为有菱形括号,所以可以正常工作
新建CallbackProducer().addIntegerListener(this::integerReceived);
//Lambda也适用于菱形括号
新建CallbackProducer().addIntegerListener(intValue->integerReceived(intValue));
//此变体也可以在不指定CallbackProducer的“T”的情况下工作
//…但如果可能的话,这是一个我宁愿避免的解决方法:-P
GenericListener integerListener=this::integerReceived;
新建CallbackProducer().addIntegerListener(integerListener);
}
私有void integerReceived(Integer intValue){
System.out.println(“接收到整数回调:“+intValue”);
}
//接受泛型侦听器的回调生产者
//有一个类型参数“T”,它与
//GenericListener的“V”,不用于本文档中的任何内容
//这是一个真正的例子,除了有助于引发编译器错误之外
公共类回调生成器{
//添加一个侦听器,该侦听器专门接受整数类型作为参数
public void addIntegerListener(GenericListener integerListener){
//只是一个伪回调来接收一些输出
integerListener.genericCallback(100);
}
}
//一个简单的通用侦听器接口,可以接受任何类型的值
//具有类型参数“V”,用于指定回调的值类型
//“V”与CallbackProducer的“T”完全无关
@功能接口
公共接口GenericListener{
作废genericCallback(V genericValue);
}
}
这是一个简短的版本,没有所有的注释混乱,只调用了两个“addIntegerListener”,其中一个会导致编译器错误
import javax.swing.*;
公共班机{
公共静态void main(最终字符串[]args){
调用器(Main::new);
}
公用干管(){
CallbackProducer1=新的CallbackProducer();
producer1.addIntegerListener(this::integerReceived);//编译器错误
CallbackProducer2=新的CallbackProducer();
producer2.addIntegerListener(this::integerReceived);//编译正常
}
私有void integerReceived(Integer intValue){
System.out.println(“接收到整数回调:“+intValue”);
}
公共类回调生成器{
public void addIntegerListener(GenericListener integerListener){
integerListener.genericCallback(100);
}
}
@功能接口
公共接口GenericListener{
作废genericCallback(V genericValue);
}
}
所有3个编译器错误都是由于您使用的是原始回调生产者。当您使用原始的CallbackProducer
时,所有类型参数都会进行类型擦除,这样,任何T
,例如您的,没有任何上限,都会变成对象
因此,addIntegerListener
方法需要一个原始的GenericListener
作为参数,integerReceived
不再适用。integerReceived
方法采用的是Integer
,而不是对象<