2014-02-24 87 views
2

我有下面的类层次结构,它只是实现了编码和解码来自给定字节数组的动物的想象功能。在泛型中的类型安全

public abstract class Animal { 
} 

class Tiger extends Animal{ 
    private String name; 

    public void setName() { 
    } 

    public String getName() { 
     return this.name; 
    } 
} 

abstract class AnimalTransformer { 
    public static <T> T decodeAnimalFromBytes(byte[] animalInBytes) { 
     return null; 
    } 

    public static byte[] encodeAnimalInBytes(Animal animal) { 
     return null; 
    } 

}

class TigerTransformer extends AnimalTransformer{ 
    public static Tiger decodeAnimalFromBytes(byte[] animalInBytes) { 
     return new Tiger(); 
    } 

    public static byte[] encodeAnimalinBytes(Tiger tiger) { 
     return new byte[0]; 
    } 
} 

在从AnimalTransformer抽象类中延伸AnimalTransformer的TigerTransformer类覆盖的方法,我得到以下警告

Type safety: The return type Tiger for decodeAnimalFromBytes(byte[]) from the type 
TigerTransformer needs unchecked conversion to conform to T 
from the type AnimalTransformer 

我明白这个警告的原因但不幸的是我不能解决它,因为我是泛型的新手。有人可以简要解释如何解决这个警告?

回答

1

首先,不要试图用静态方法“覆盖”。它不会像你认为的那样工作 - “覆盖”的静态方法仍然可以通过偏僻(偶然)的方式从子类访问。如果您想重写行为,请使用本地方法。

警告正在产生,因为Tiger方法签名与超级方法承诺不兼容 - 客户端选择的任何类<T>可以解码为,这是一个非常大的,无法实现的承诺。

一个更好的方法是:

abstract class AnimalTransformer<T extends Animal> { 
    public T decodeAnimalFromBytes(byte[] animalInBytes) { 
    return null; 
    } 
    public static byte[] encodeAnimalInBytes(T animal) { 
    return null; 
    } 
} 

class TigerTransformer extends AnimalTransformer<Tiger> { 
    public Tiger decodeAnimalFromBytes(byte[] animalInBytes) { 
    return new Tiger(); 
    } 
    public byte[] encodeAnimalinBytes(Tiger tiger) { 
     return new byte[0]; 
    } 
} 

这代表你想更清楚地进行建模的东西 - 一个AnimalTransformer提供的Animal一些子类转化方法,它是由子类,或匿名的实现,澄清哪些。

+0

但我只需要以静态方式访问功能,即通过不实例化TigerTransformer,我想像TigerTransformer.encodeToBytes()那样访问它,因为实例化这种类不合逻辑。不能以静态方式访问? –

+0

它不合逻辑吗?如果您需要,如果您担心多个实例,则可以将TigerTransformer作为单例提供。 (或者,更好的是,提供所有变压器的AnimalTransformers类)。如果你真的不想实例化它,那么使用继承和遗传是没有意义的 - 你可以选择其中一个。 – torquestomp

+0

谢谢..我的意思是这个类只是提供了编码和解码的功能,所以用它们的类名称来调用它们,比如声明静态,我认为它比实例化更好。并且使用单例设计模式这些课程对我来说很好,所以我会一起去。 –

2

请注意,使AnimalTransformer的方法静态是没有用的。静态方法不会通过继承来相互覆盖。此外,您不绑定变换器处理解码对象类型的数据类型(例如,TigerTransformer可以返回Horse对象)。

我会做,而不是下面的,我认为是更安全的类型:

所有的
abstract class AnimalTransformer <T> { 
    public abstract T decodeAnimalFromBytes(byte[] animalInBytes); 

    public abstract byte[] encodeAnimalInBytes(T animal); 
}