5

我有一个编组器的以下接口,它将Object一个DataNode对象编组并返回:

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

}

为了确保我能够为对象获取正确的编组器,我还有Class<T> getDataClass()返回其类的方法(由于类型擦除,编译后会丢失)。

现在我想在一个能够编组这样类型的对象的类中实现这个接口Octree<T>

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


}

我现在的问题是(当然)Octree.class不是类型Class<Octree<T>>,而是非泛型类型Class<Octree>,Java 不允许我将其转换为Class<Octree<T>>.

现在的问题是:有没有比我已经考虑过的两种更优雅的方法来解决这个问题:

  • 将接口中的返回值从更改Class<T>Class<?>
  • 将类签名更改OctreeMarshallerpublic class OctreeMarshaller implements DataMarshaller<Octree>
4

2 回答 2

4

没有你的实例Octree<T>就不能构造类型的类对象Class<Octree<T>>。但是因为我们知道(由于类型擦除)Octree在运行时只有一个类,所以可以安全地编写

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

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

    [...]
}
于 2013-10-26T13:52:17.500 回答
1

对于Class泛型类型,您需要双重转换:

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

古怪,但它的工作原理。

于 2013-10-26T13:51:41.533 回答