【问题标题】:lambda vs anonymous classlambda 与匿名类
【发布时间】:2017-05-16 15:15:35
【问题描述】:

我有以下代码:

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: Could not resolve payload typeEvent&lt;T&gt; 类的 getPayload() 引起。

lamdbasgenerics 缺少什么?

【问题讨论】:

  • 使用Event::&lt;NavigationEvent&gt;getPayload 明确类型
  • 附带说明,这些不是 lambda,而是函数引用。它不适用于 lambda,因为 lambda 不能用于具有泛型类型的函数式接口
  • 你能分享整个堆栈跟踪吗?
  • @njzk2: getPayload 不是通用方法,因此,使用 Event::&lt;NavigationEvent&gt;getPayload 没有意义,类型参数将被忽略。并且 lambda 表达式将起作用,与方法引用的程度相同。

标签: generics lambda java-8 anonymous-class


【解决方案1】:

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

问题似乎与eventBus.subscribe 在内部所做的有关。由于类型擦除,只有一个subscribe(EventBusListener)方法,不知道你传入的是EventBusListener&lt;NavigationEvent&gt;还是EventBusListener&lt;NotificationEvent&gt;

正如消息“Could not resolve payload type”所表明的那样,它无论如何都会尝试找出实际的有效负载类型,这意味着使用反射。这仅适用于 reifiable,即非泛型类型。您的匿名内部类是 reifiable 类型,它们本身不是通用的,而是具有通用的超类/接口,可以通过 getGenericSuperclass() resp 进行检查。 getGenericInterfaces().

在该上下文中使用方法引用或 lambda 表达式的问题在于,如果接口是泛型的,则生成的运行时类将不会reifiable,即您无法找出实际的通过反射类型参数。就像你写的干草一样

eventBus.subscribe(Event::getPayload);

除非有允许您显式指定有效负载类型的重载方法,否则这不适用于 lambda 表达式或方法引用。

取决于框架如何在内部解析类型,使用 reifiable 接口可能会起作用,例如

interface NavigationEventListener extends EventBusListener<NavigationEvent> {}
…

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

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

【讨论】:

    猜你喜欢
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 2017-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多