Java:类型安全性 - 未经检查的转换

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?
2个回答

11

当你将非参数化类型(Object)强制转换为参数化类型(LinkedList)时,Java会报错。这是为了告诉你它可以是任何类型。这与第一个转换并没有什么不同,只是第一个会在不是该类型时生成ClassCastException异常,而第二个则不会。

这一切都归结于类型擦除。在运行时,LinkedList实际上只是一个LinkedList。你可以把任何东西放进去,它不会像第一个示例那样生成ClassCastException异常。

通常为了消除这个警告,你需要做类似以下的事情:

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

queryForList() 返回一个 List (无参) 其中你知道内容将是 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");

是完全合法的。


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

在这些方法中,你需要进行适当的转换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接