2013-10-26 16 views
5

Tôi có giao diện sau cho một marshaller rằng Marshalls một Object đến một đối tượng DataNode và lưng:Java: Generics Inheritance

public interface DataMarshaller<T> { 

    /** 
    * returns the actual class that this marshaller is capable of marshalling. 
    * @return 
    */ 
    Class<T> getDataClass(); 

    /** 
    * marshalls the object to a DataNode 
    * 
    * @param object 
    * @return 
    */ 
    DataNode marshal(T object); 

    /** 
    * unmarshalls the object from a DataNode 
    * 
    * @param node 
    * @return 
    */ 
    T unMarshal(DataNode node); 

} 

Để chắc chắn rằng tôi có thể có được marshaller chính xác cho một đối tượng tôi cũng có phương thức Class<T> getDataClass() trả về lớp của nó (có thể đã bị mất sau khi biên dịch vì loại xóa).

Bây giờ tôi muốn thực hiện giao diện này trong một lớp học mà có thể sắp xếp các đối tượng của loại Octree<T> như thế này:

public class OctreeMarshaller<T> implements DataMarshaller<Octree<T>> { 

    @Override 
    public Class<Octree<T>> getDataClass() { 
     return Octree.class; //<- compiletime error 
    } 

    @Override 
    public DataNode marshal(Octree<T> object) { 
     //... 
    } 

    @Override 
    public Octree<T> unMarshal(DataNode node) { 
     //... 
    } 


} 

Vấn đề của tôi bây giờ mà (tất nhiên) Octree.class không phải là loại Class<Octree<T>> nhưng thay vì là của loại không chung chung Class<Octree> và Java sẽ không cho phép tôi truyền nó đến Class<Octree<T>>.

Câu hỏi đặt ra bây giờ là: là có một cách elegent hơn để giải quyết đó hơn hai tôi đã xem xét:

  • thay đổi giá trị trả về trong giao diện Class<T>-Class<?>
  • thay đổi chữ ký lớp OctreeMarshaller để public class OctreeMarshaller implements DataMarshaller<Octree>
+0

Không chắc chắn những gì bạn đang sử dụng 'Class' đối tượng cho, nhưng có lẽ siêu tokens loại là những gì bạn đang tìm kiếm: http://gafter.blogspot.sk/2006/12/super-type-tokens.html. Chúng là một cách để thể hiện các kiểu chung chung "lồng nhau" khi chạy, mặc dù bất kỳ loại kiểm tra thực tế nào mà bạn phải tự thực hiện. (Đó là, bạn không tự động nhận được một "thông minh hơn" 'Class.cast()' hoặc bất cứ điều gì.) – millimoose

Trả lời

4

Không có trường hợp Octree<T> bạn không thể tạo đối tượng lớp loại Class<Octree<T>>. Nhưng kể từ khi chúng ta biết (do loại tẩy xoá) chỉ có một lớp Octree trong thời gian chạy, nó an toàn để viết

public class OctreeMarshaller<T> implements DataMarshaller<Octree<T>> { 

    @Override 
    @SuppressWarnings("unchecked") 
    public Class<Octree<T>> getDataClass() { 
     return (Class<Octree<T>>)(Class<?>)Octree.class; 
    } 

    [...] 
} 
+0

Điều này giải quyết vấn đề của tôi. Tôi chưa bao giờ nghĩ đến việc tạo gấp đôi nó - cảm ơn! :) – Entrusc

1

với Class của một loại chung chung, bạn cần có một dàn diễn viên kép:

public Class<Octree<T>> getDataClass() { 
    return (Class<Octree<T>>)(Class<?>)Octree.class; 
} 

Whacky, nhưng nó hoạt động.

+0

Nhưng đúc là một mâu thuẫn với loại an toàn – siledh