2010-06-12 4 views
11

Với một giao diện chung chung nhưChú làm cho có sẵn generic loại

interface DomainObjectDAO<T> 
{ 
    T newInstance(); 
    add(T t); 
    remove(T t); 
    T findById(int id); 
    // etc...  
} 

Tôi muốn tạo ra một subinterface chỉ định tham số kiểu:

interface CustomerDAO extends DomainObjectDAO<Customer> 
    { 
     // customer-specific queries - incidental. 
    } 

Việc thực hiện cần phải biết các mẫu thực tế loại tham số, nhưng tất nhiên loại xóa nghĩa là không có sẵn trong thời gian chạy. Có một số chú thích mà tôi có thể đưa vào để khai báo kiểu giao diện không? Một cái gì đó như

@GenericParameter(Customer.class) 
    interface CustomerDAO extends DomainObjectDAO<Customer> 
    { 
    } 

Việc triển khai có thể tìm nạp chú thích này từ giao diện và sử dụng nó làm thay thế cho truy cập loại generic chung.

Một số nền:

Giao diện này được thực hiện sử dụng JDK proxy động như đã nêu here. Phiên bản không chung của giao diện này đã hoạt động tốt, nhưng sẽ tốt hơn nếu sử dụng Generics và không phải tạo ra các phương thức trong một subinterface chỉ để xác định loại đối tượng miền. Generics và proxy chăm sóc hầu hết mọi thứ, nhưng loại thực tế là cần thiết trong thời gian chạy để thực hiện phương thức newInstance, trong số những thứ khác.

+1

Bạn đã cố gắng viết chú thích của riêng mình chưa? –

+0

@Lauri - Tôi đã không tự làm, nhưng tôi có thể làm điều đó, tôi thấy rất nhiều câu hỏi về generics và thất vọng về loại tẩy xoá, vì vậy tôi hy vọng điều này đã được thực hiện rồi. – mdma

Trả lời

7

Có thể tìm thấy những đối số kiểu thực tế của người Dao tiểu giao diện (CustomerDAO), bằng cách gọi các phương pháp sau đây:

import java.lang.reflect.ParameterizedType; 

public static Class<?> getDomainClass(final Class<?> daoInterface) { 
    ParameterizedType type = (ParameterizedType) daoInterface.getGenericInterfaces()[0]; 
    return (Class<?>) type.getActualTypeArguments()[0]; 
} 

Khi bạn gọi nó như

Class<?> domainClass = getDomainClass(daoInterface); 

với daoInterface == CustomerDAO.class , sau đó bạn sẽ nhận được domainClass == Customer.class.

Khi triển khai, DaoFactory thực hiện cuộc gọi này và sử dụng số domainClass làm đối số hàm tạo cho số DaoInvocationHandler.

+1

Cảm ơn! Đây là giải pháp. Theo http: //blog.springsource.com/2006/09/29/khai thác-generics-metadata/không phải tất cả thông tin chung được xóa - đặc biệt, thông tin tĩnh được duy trì. – mdma

1

Triển khai cần biết loại thông số mẫu thực tế.

Chắc chắn, bất kỳ thực hiện CustomerDao ngầm biết rằng tham số kiểu là Customer. Nó đang triển khai DomainObjectDAO<Customer> không phải DomainObjectDAO<T>.

Sự cố chỉ xảy ra nếu lớp CustomerDao mở rộng lớp trừu tượng chung và lớp trừu tượng chung cần biết loại thực tế là T. Nhưng bạn có thể đối phó với điều đó bằng cách chuyển đối tượng Lớp cho T (trong trường hợp này là Customer.class) vào lớp cha làm đối số hàm tạo.

+0

Tôi sẽ viết rằng trong câu hỏi tôi có thể truyền kiểu thực tế như một hàm tạo cho InvocationHandler, nhưng tôi đã tự hỏi nếu có một chú thích để thực hiện cùng một công việc - kiểu thuộc về giao diện chứ không phải thực hiện. – mdma