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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1490134/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 16:43:54  来源:igfitidea点击:

Java: Type safety - unchecked cast

javatype-safety

提问by Nick Heiner

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?

采纳答案by OscarRyz

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.

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

回答by cletus

Java complains like that when you cast a non-parameterized type (Object) to a parameterized type (LinkedList). 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.

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

It all comes down to type erasure. A LinkedList at runtime is really just a LinkedList. You can put anything in it and it won't generate a ClassCastException like the first example.

这一切都归结为类型擦除。运行时的 LinkedList 实际上只是一个 LinkedList。您可以将任何内容放入其中,它不会像第一个示例那样生成 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() 返回一个列表(非参数化),您知道其中的内容属于Something 类。

The other aspect to this is that arrays in Java are covariant, meaning they retain runtime type information. For example:

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

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.

是完全合法的。