在泛型中键入安全性

时间:2014-02-24 06:31:54

标签: java generics type-safety

我有以下层次的类,它们只是实现了从给定的bytearrays中编码和解码动物的想象功能。

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];
    }
}

在来自TigerTransformer类中的AnimalTransformer抽象类的覆盖方法中,它扩展了AnimalTransformer,我收到以下警告

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

我理解这个警告的原因,但不幸的是我无法解决它,因为我是仿制药的新手。有人可以简要解释如何纠正这种警告吗?

2 个答案:

答案 0 :(得分:2)

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

我会做以下事情,我认为它更安全:

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

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

答案 1 :(得分: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];
  }
}

这代表了你想要更清楚地建模的内容 - AnimalTransformerAnimal的某些子类提供了转换方法,并且由子类或匿名实现来明确哪个。< / p>