2017-08-05 1 views
6

は、我々は次のクラスを持っているとしましょう:Javaでは、ジェネリック型のクラスを持つ変数にメソッド参照を割り当てることは可能ですか?

Service service = new Service(); 
EventListener<ServiceEvent> listener = service::onServiceEvent; 

が、この1:

interface Event { 
} 

@FunctionalInterface 
interface EventListener<T extends Event> { 
    void onEvent(T event); 
} 

class Service { 

    class ServiceEvent implements Event { 
    } 

    public void onServiceEvent(ServiceEvent event) { 
    } 
} 

なぜ以下の割り当ては問題なくコンパイルん

Service service = new Service(); 
EventListener<? extends Event> anotherListener = service::onServiceEvent; 

がこれに失敗しますコンパイルエラー:

Error: java: incompatible types: invalid method reference incompatible types: Event cannot be converted to Service.ServiceEvent

+0

'EventListener <? extends Event> anotherListener = null; '? –

+0

@MikeNakisそれは完全に合法です。それは問題なくコンパイルされます。 – maseev

+2

私はあなたがどこから来ているのかを知っていますが、別の方法で考えることができます。 'anotherListener'の定義は、' Event'を拡張するもので 'anotherListener.onEvent'を呼び出すことを可能にします。コンパイラはそのような場合に適切な使用を保証することはできず、ジェネリックスはすべてコンパイル時に型の安全性に関するものです。 – Dave

答えて

2
public void onServiceEvent(ServiceEvent event) {} 

これは、ServiceEventパラメータのみを受け入れます。ただ、好き:

EventListener<ServiceEvent> listener = service::onServiceEvent; 

しかし:

EventListener<? extends Event> anotherListener 

EventタイプだけでなくServiceEventでなく、すべてのサブタイプを受け入れることができます。したがって、タイプの不一致

+0

そして、あなたは 'anotherListener = listener'を問題なく実行できます。 – RealSkeptic

+0

@RealSkepticええ、わかりました - 私は割り当ての順序を変更しました –

+0

@RealSkeptic最近よく似たような質問をここでよく見ました - 私はそれを見つけようとします –

関連する問題