2017-08-05 21 views
6

Hãy nói rằng chúng tôi đã có các lớp sau:Trong Java có thể gán một tham chiếu phương thức cho một biến có lớp có kiểu chung không?

interface Event { 
} 

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

class Service { 

    class ServiceEvent implements Event { 
    } 

    public void onServiceEvent(ServiceEvent event) { 
    } 
} 

Tại sao sự phân công sau biên dịch mà không cần bất kỳ vấn đề:

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

nhưng điều này:

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

thất bại với điều này lỗi biên dịch:

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

+0

Điều gì sẽ xảy ra nếu bạn nói 'EventListener anotherListener = null; '? –

+0

@MikeNakis Nó hoàn toàn hợp pháp. Nó sẽ được biên dịch mà không có bất kỳ vấn đề gì. – maseev

+2

Tôi nhận được nơi bạn đang đến từ, nhưng hãy nghĩ về nó theo một cách khác. Định nghĩa 'anotherListener' cho phép bạn gọi' anotherListener.onEvent' với bất cứ thứ gì mở rộng 'Event'. Trình biên dịch không thể đảm bảo sử dụng thích hợp trong trường hợp đó, và generics là tất cả về an toàn kiểu tại thời gian biên dịch. – Dave

Trả lời

2
public void onServiceEvent(ServiceEvent event) {} 

Chỉ chấp nhận thông số ServiceEvent. Giống như:

EventListener<ServiceEvent> listener = service::onServiceEvent; 

nhưng:

EventListener<? extends Event> anotherListener 

thể chấp nhận không chỉ ServiceEvent mà còn tất cả các phân nhóm của các loại Event. Do đó, loại không khớp

+0

Và bạn có thể làm 'anotherListener = listener' mà không gặp bất kỳ vấn đề gì. – RealSkeptic

+0

@RealSkeptic vâng, tôi thấy - Tôi đã đổi thứ tự của bài tập –

+0

@RealSkeptic Tôi đã nhìn thấy một câu hỏi tương tự ở đây gần đây với một câu trả lời hay - Tôi sẽ cố gắng tìm ra rằng –

Các vấn đề liên quan