2017-05-22 13 views
7

Với các định nghĩa sau đây:Tại sao Java yêu cầu có 2 phương thức được khai báo khi generics bị ràng buộc có liên quan?

public interface BaseService<T, ID> { 

    T findOne(ID id); 

} 

public class BaseServiceImpl<T,ID extends Serializable> implements BaseService<T, ID> { 

    @Override 
    public T findOne(ID id) { 
     return null; 
    } 

} 

Tại sao BaseServiceImpl.class.getDeclaredMethods() trở lại 2 phương pháp:

  • public java.lang.Object BaseServiceImpl.findOne(java.io.Serializable)
  • public java.lang.Object BaseServiceImpl.findOne(java.lang.Object)

Có cách nào để lọc những hiểu?

+3

Bạn có thể kiểm tra xem chữ ký 'Object' có được đánh dấu là phương thức cầu nối không? – chrylis

+0

@chrylis Vâng, thực sự là vậy! Điều đó giải quyết vấn đề trước mắt của tôi. Cảm ơn nhiều! Nếu bạn quan tâm để mở rộng nó một chút vào một câu trả lời, tôi muốn được hạnh phúc để upvote/chấp nhận nó. – kaqqao

+0

Tôi không hiểu các quy tắc cầu cũng đủ để viết một câu trả lời đúng, tôi chỉ nhận thấy rằng nó phù hợp với mô hình mà tôi đã thu thập được. – chrylis

Trả lời

5

Đây là hậu quả của việc xóa kiểu. Ở cấp mã byte, chữ ký chung chỉ là thuộc tính bổ sung của các phương thức, không được sử dụng cho công văn phương thức của JVM. Chữ ký cấp mã byte thực tế bắt nguồn từ loại đầu tiên của ràng buộc của biến loại, ví dụ: đối với biến loại T extends Number&Serializable, thay thế chữ ký thô cho T sẽ là Number.

Đối với lời tuyên bố của mình,

public interface BaseService<T, ID> { 
    T findOne(ID id); 
} 

TID được thay thế bằng Object; chữ ký xóa của phương thức là Object findOne(Object).

Đối với việc kê khai kiểu phụ

public class BaseServiceImpl<T,ID extends Serializable> implements BaseService<T, ID> { 
    @Override 
    public T findOne(ID id) { 
     return null; 
    } 
} 

kiểu xóa của ID extends SerializableSerializable, gây ra các phương pháp thực hiện để có chữ ký bị xóa Object findOne(Serializable).

Để đảm bảo rằng mã sử dụng giao diện BaseService, gọi phương thức Object findOne(Object), sẽ tìm ra phương pháp thực hiện, trình biên dịch sẽ tạo ra một bridge method có chữ ký Object findOne(Object) và bao gồm một phái đoàn đồng bằng để Object findOne(Serializable), thực hiện các loại phôi khi cần thiết.

Bạn có thể xác định phương thức cầu bằng cách gọi isBridge() trên ví dụ Method.

Bạn cũng có thể sử dụng kiến ​​thức về cách xóa công trình loại ảnh hưởng đến kết quả. Bằng cách thay đổi việc kê khai để

public class BaseServiceImpl<T, ID extends Object&Serializable> 
     implements BaseService<T, ID> { 
    @Override 
    public T findOne(ID id) { 
     return null; 
    } 
} 

không có sự khác biệt về ngữ nghĩa liên quan đến hệ thống kiểu chung chung, nhưng xóa các ID extends Object&Serializable sẽ Object, do đó, tẩy xoá kết quả của phương pháp findOne sẽ giống hệt nhau để xóa bỏ hoàn của giao diện do đó, không cần phương thức cầu trong trường hợp này.

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