Generics – lambda and anonymous classes

I have the following code:

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 told me that I can replace these two anonymous classes with lambda expressions, such as:

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

Compilation works normally, but the following error occurs when the runtime application crashes: Java Lang. illegalargumentexception: cannot resolve valid content type class caused by getpayload() of event < T >

Lamdbas and generics what do I lack?

Solution

There is no problem with your method reference, but the subsystem does not throw illegalargumentexception

It seems that the problem is with eventbus Subscribe is related to its internal role Due to type erasure, there is only one subscription (eventbuslistener) method. I don't know whether you passed in eventbuslistener < navigationevent > or eventbuslistener < notificationevent >

As the message "cannot resolve payload type" shows, it tries to find the actual payload type, which means using reflection This applies only to renewable, i.e. non universal types Your anonymous inner class is a replicable type, not generic, but has a generic superclass / interface, which can be checked through getgenericsuperclass () resp getGenericInterfaces().

The problem with using method references or lambda expressions in this context is that if the interface is generic, the generated runtime class will not be renewable, that is, you cannot find the actual type parameters through reflection It's like you wrote in hay

eventBus.subscribe(Event::getPayload);

This does not apply to lambda expressions or method references unless there are overloaded methods that allow you to explicitly specify valid content types

Depending on how the framework resolves types internally, it may be effective to use regenerated interfaces, for example,

interface NavigationEventListener extends EventBusListener<NavigationEvent> {}
…

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

Of course, if you want to instantiate multiple types of listeners, this will only pay off. Otherwise, you can continue to use anonymous inner classes (unless it's your problem for them to capture this instance)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>