2009-09-29 30 views
4

这里是我的代码:的Java:类型安全 - 选中投

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?

回答

3

因为在这里:

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

里面那些方法你必须做适当的转换。

12

当您将非参数化类型(Object)转换为参数化类型(LinkedList)时,Java会发出类似的抱怨。这是告诉你,它可能是任何东西。它与第一次投射真的没什么两样,除非第一次会产生一个ClassCastException,如果它不是那种类型,但第二次不会。

这一切归结为类型擦除。运行时的LinkedList实际上只是一个LinkedList。你可以放入任何东西,它不会像第一个例子那样产生ClassCastException。

往往摆脱这种警告,你必须做的是这样的:

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

其中的queryForList()返回一个列表(非参数),你知道的内容将是类的东西。

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

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

是完全合法的。