简体   繁体   English

Java:输入安全性 - 未经检查的强制转换

[英]Java: Type safety - unchecked cast

Here is my code: 这是我的代码:

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

It gives this warning for the LinkedList: 它为LinkedList提供此警告:

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

Why does it complain about the linked list and not MyGenome? 为什么它会抱怨链表而不是MyGenome?

Java complains like that when you cast a non-parameterized type (Object) to a parameterized type (LinkedList). 当你将非参数化类型(Object)转换为参数化类型(LinkedList)时,Java会抱怨这样。 It's to tell you that it could be anything. 它告诉你它可能是任何东西。 It's really no different to the first cast except the first will generate a ClassCastException if it is not that type but the second won't. 它与第一个强制转换没有什么不同,除非第一个将生成ClassCastException,如果它不是那个类型但第二个不会。

It all comes down to type erasure. 这一切都归结为类型擦除。 A LinkedList at runtime is really just a LinkedList. 运行时的LinkedList实际上只是一个LinkedList。 You can put anything in it and it won't generate a ClassCastException like the first example. 您可以在其中放置任何内容,它不会像第一个示例那样生成ClassCastException。

Often to get rid of this warning you have to do something like: 经常要摆脱这个警告你必须做的事情如下:

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

where queryForList() returns a List (non-parameterized) where you know the contents will be of class Something. 其中queryForList()返回一个List(非参数化),你知道内容将是Something类。

The other aspect to this is that arrays in Java are covariant , meaning they retain runtime type information. 另一方面是Java中的数组是协变的 ,这意味着它们保留了运行时类型信息。 For example: 例如:

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

will throw a exception. 会抛出异常。 But: 但:

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

is perfectly legal. 是完全合法的。

Because here: 因为这里:

MyGenome genome = (MyGenome) data[0];

You are not using generics 你没有使用泛型

And here 和这里

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

You are using them. 你正在使用它们。

That's just a warning, you are mixing types in the data array. 这只是一个警告,你在数据数组中混合类型。 If you know what are you doing ( I mean, if the second element do contains a LinkedList ) you can ignore the warning. 如果您知道自己在做什么(我的意思是,如果第二个元素包含LinkedList ),您可以忽略该警告。

But better would be to have an object like this: 但更好的方法是拥有一个这样的对象:

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

And have to methods returning proper things, prior to a correct conversion so you end up with: 并且必须在正确的转换之前返回正确的方法,以便最终得到:

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

Inside those methods you have to do proper transformations. 在这些方法中,你必须进行适当的转换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM