2013-10-26 20 views
5

Ben geri DataNode nesne ve bir Object marshalls bir Marshaller için aşağıdaki arayüz:Java: Jenerik Kalıtım

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); 

} 

ben bir nesne için doğru Marshaller almanız mümkün değilim emin olmak için ben ayrıca sınıfını döndüren Class<T> getDataClass() yöntemine de sahiptir (bu, tip silme nedeniyle derlendikten sonra kaybolacaktır). Benim sorunum şimdi Octree.class tip Class<Octree<T>> ait değil (tabii ki) daha ziyade

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) { 
     //... 
    } 


} 

olduğunu

:

Şimdi böyle tip Octree<T> nesneleri sıralamakta edebilen bir sınıfta bu arabirim uygulamak istedi jenerik olmayan tür Class<Octree> ve Java, Class<Octree<T>>'a yayınlamama izin vermiyor.

soru şimdi: Zaten kabul ikiden o çözmek için daha elegent yolu yoktur:

  • değişiklik Class<?>
  • değişim sınıf imzası için Class<T> gelen arayüzde dönüş değeri OctreeMarshaller jenerik Çeşidi Class ile public class OctreeMarshaller implements DataMarshaller<Octree>
+0

Değil Ne aradığınız: http://gafter.blogspot.sk/2006/12/super-type-tokens.html. Gerçek tipler, kendinizi uygulamak zorunda kalmanıza rağmen, çalışma zamanında "iç içe" jenerik türlerini ifade etmenin bir yoludur. (Yani, otomatik olarak "daha akıllı" olan "Class.cast()" veya herhangi bir şey almazsınız.) – millimoose

cevap

4

Octree<T> örneği olmadan, Class<Octree<T>> türünde bir sınıf nesnesini yapılandıramazsınız. Biz (nedeniyle tip silinmeye kadar) biliyorum çalıştırma süresinde yalnızca bir sınıf Octree olmadığından Ama, yazmaya güvenli sizin için `Class` nesnesini kullanıyoruz, ama belki süper tip belirteçleri ne olduğundan emin

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

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

    [...] 
} 
+0

Bu, benim sorunumu çözdü. Çift döküm yapmayı hiç düşünmemiştim - teşekkürler! :) – Entrusc

1

için, bir çift döküm gerekir:

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

Vay canına, ama işe yarıyor.

+0

Ancak döküm, güvenlik yazımı için bir çelişkidir – siledh