5

这是我的代码:

Object[] data = GeneComparison.readData(files);
MyGenome genome = (MyGenome) data[0];
LinkedList<Species> breeds = (LinkedList<Species>) data[1];

它为 LinkedList 提供以下警告:

Type safety: Unchecked cast from Object to LinkedList<Species>

为什么它抱怨的是链表而不是 MyGenome?

4

2 回答 2

12

当您将非参数化类型(Object)转换为参数化类型(LinkedList)时,Java 会这样抱怨。它是告诉你它可以是任何东西。这与第一个演员并没有什么不同,除了第一个演员不是那种类型时会生成 ClassCastException 而第二个不会。

这一切都归结为类型擦除。运行时的 LinkedList 实际上只是一个 LinkedList。您可以在其中放入任何内容,它不会像第一个示例那样生成 ClassCastException。

通常要摆脱此警告,您必须执行以下操作:

@SuppressWarning("unchecked")
public List<Something> getAll() {
  return getSqlMapClient.queryForList("queryname");
}

其中 queryForList() 返回一个列表(非参数化),您知道其中的内容将属于 ​​Something 类。

另一方面,Java 中的数组是协变的,这意味着它们保留运行时类型信息。例如:

Integer ints[] = new Integer[10];
Object objs[] = ints;
objs[3] = "hello";

会抛出异常。但:

List<Integer> ints = new ArrayList<Integer>(10);
List<Object> objs = (List<Object>)ints;
objs.add("hello");

是完全合法的。

于 2009-09-29T01:33:30.107 回答
4

因为这里:

MyGenome genome = (MyGenome) data[0];

您没有使用泛型

和这里

LinkedList<Species> breeds = (LinkedList<Species>) data[1];

你正在使用它们。

这只是一个警告,您正在混合数据数组中的类型。如果您知道自己在做什么(我的意思是,如果第二个元素确实包含LinkedList),您可以忽略警告。

但最好有一个像这样的对象:

class Anything {
    private Object [] data;
    public Anything( Object [] data ) {
         this.data = data;
    }
    public Gnome getGnome() {
    .....
    }
    public List<Species> getBreeds() {
    ......
    }
 }

并且必须在正确转换之前返回正确的东西的方法,因此您最终得到:

Anything anything = new Anything( GeneComparison.readData(files) );
MyGenome genome             = anything.getGnome(); // similar to data[0]
LinkedList<Species> breeds = anything.getBreeds(); // similar to data[1];

在这些方法中,您必须进行适当的转换。

于 2009-09-29T01:38:15.890 回答