lou*_*ros 6 generics lambda anonymous-class java-8
我有以下代码:
eventBus.subscribe(new EventBusListener<NavigationEvent>() {
@Override
public void onEvent(Event<NavigationEvent> event) {
event.getPayload();
}
});
eventBus.subscribe(new EventBusListener<NotificationEvent>() {
@Override
public void onEvent(Event<NotificationEvent> event) {
event.getPayload();
}
});
Run Code Online (Sandbox Code Playgroud)
IntelliJ告诉我,我可以用lambda表达式替换这两个匿名类,如:
eventBus.subscribe((EventBusListener<NavigationEvent>) Event::getPayload);
eventBus.subscribe((EventBusListener<NotificationEvent>) Event::getPayload);
Run Code Online (Sandbox Code Playgroud)
编译效果很好,但在运行时,出现以下错误的应用程序崩溃:java.lang.IllegalArgumentException: Could not resolve payload type引起getPayload()的Event<T>类.
我是缺少什么lamdbas和generics?
您的方法引用没有任何问题,但该IllegalArgumentException子系统也没有抛出.
似乎问题与eventBus.subscribe内部的问题有关.由于类型擦除,只有一种subscribe(EventBusListener)方法,不知道你是否通过了EventBusListener<NavigationEvent>或EventBusListener<NotificationEvent>.
正如消息"无法解析有效负载类型"所示,它会尝试找出实际的有效负载类型,这意味着使用反射.这仅适用于可回收的,即非通用类型.你的匿名内部类是可复制的类型,不是通用的,而是具有可以通过getGenericSuperclass()resp 检查的通用超类/接口.getGenericInterfaces().
在该上下文中使用方法引用或lambda表达式的问题是,如果接口是通用的,则生成的运行时类将不可再生,即您无法通过Reflection找到实际的类型参数.这就像你干草写的那样
eventBus.subscribe(Event::getPayload);
Run Code Online (Sandbox Code Playgroud)
除非存在允许您明确指定有效内容类型的重载方法,否则这将不适用于lambda表达式或方法引用.
取决于框架如何在内部解析类型,使用可重新生成的接口可能有效,例如
interface NavigationEventListener extends EventBusListener<NavigationEvent> {}
…
eventBus.subscribe((NavigationEventListener)Event::getPayload);
Run Code Online (Sandbox Code Playgroud)
当然,如果您要实例化多个类型的监听器,这只会得到回报,否则,您可以继续使用匿名内部类(除非他们捕获this实例是您的问题).
| 归档时间: |
|
| 查看次数: |
615 次 |
| 最近记录: |