泛型 – lambda与匿名类

前端之家收集整理的这篇文章主要介绍了泛型 – lambda与匿名类前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有以下代码
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();
    }
});

IntelliJ告诉我,我可以用lambda表达式替换这两个匿名类,如:

eventBus.subscribe((EventBusListener<NavigationEvent>) Event::getPayload);
eventBus.subscribe((EventBusListener<NotificationEvent>) Event::getPayload);

编译工作正常但在运行时应用程序崩溃时出现以下错误:java.lang.IllegalArgumentException:无法解析由事件< T>的getPayload()引起的有效内容类型类.

lamdbas和generics我缺少什么?

解决方法

您的方法引用没有任何问题,但该子系统也没有抛出IllegalArgumentException.

似乎问题与eventBus.subscribe在内部的作用有关.由于类型擦除,只有一个订阅(EventBusListener)方法,不知道您是否传入了EventBusListener< NavigationEvent>或EventBusListener< NotificationEvent>.

正如消息“无法解析有效负载类型”所示,它会尝试找出实际的有效负载类型,这意味着使用反射.这仅适用于可再生的,即非通用的类型.你的匿名内部类是可复制的类型,不是通用的,而是具有通用的超类/接口,可以通过getGenericSuperclass() resp进行检查. getGenericInterfaces().

在该上下文中使用方法引用或lambda表达式的问题是,如果接口是通用的,则生成的运行时类将不可再生,即您无法通过Reflection找到实际的类型参数.这就像你干草写的那样

eventBus.subscribe(Event::getPayload);

除非存在允许您明确指定有效内容类型的重载方法,否则这将不适用于lambda表达式或方法引用.

取决于框架如何在内部解析类型,使用可重新生成的接口可能有效,例如,

interface NavigationEventListener extends EventBusListener<NavigationEvent> {}
…

eventBus.subscribe((NavigationEventListener)Event::getPayload);

当然,如果您要实例化多个类型的监听器,这只会得到回报,否则,您可以继续使用匿名内部类(除非他们捕获此实例是您的问题).

原文链接:https://www.f2er.com/java/120266.html

猜你在找的Java相关文章