本文介绍了为什么List< Number>不是List< Object>的子类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public void wahey(List<Object> list) {}

wahey(new LinkedList<Number>());

对方法的调用不会进行类型检查。我甚至不能投入如下的参数:

The call to the method will not type-check. I can't even cast the parameter as follows:

wahey((List<Object>) new LinkedList<Number>());



从我的研究中,我收集到不允许这种情况的原因是类型安全。如果我们被允许做上述事情,那么我们可以有以下:

From my research, I have gathered that the reason for not allowing this is type-safety. If we were allowed to do the above, then we could have the following:

List<Double> ld;
wahey(ld);

在方法wahey中,我们可以在输入列表中添加一些字符串code> List< Object> 引用)。现在,在方法调用之后,ld引用具有 List< Double> 的列表,但是实际的列表包含一些String对象!

Inside the method wahey, we could add some Strings to the input list (as the parameter maintains a List<Object> reference). Now, after the method call, ld refers to a list with a type List<Double>, but the actual list contains some String objects!

这似乎不同于正常的方式Java没有泛型。例如:

This seems different to the normal way Java works without generics. For instance:

Object o;
Double d;
String s;

o = s;
d = (Double) o;

我们在这里做的本质上是一样的,除了这将通过编译时检查,在运行时失败。具有列表的版本将无法编译。

What we are doing here is essentially the same thing, except this will pass compile-time checks and only fail at run-time. The version with Lists won't compile.

这让我相信这只是一个关于泛型的类型限制的设计决策。

This leads me to believe this is purely a design decision with regards to the type restrictions on generics. I was hoping to get some comments on this decision?

推荐答案

在无泛型示例中,您正在做的是一个类型转换,这说明你在做类型不安全的事情。与泛型的等价将是:

What you are doing in the "without generics" example is a cast, which makes it clear that you are doing something type-unsafe. The equivalent with generics would be:

Object o;
List<Double> d;
String s;

o = s;
d.add((Double) o);

其行为方式相同(编译,但运行时失败)。不允许您询问的行为的原因是因为它会允许隐式类型不安全的操作,这在代码中很难注意到。例如:

Which behaves the same way (compiles, but fails at runtime). The reason for not allowing the behavior you're asking about is because it would allow implicit type-unsafe actions, which are much harder to notice in code. For example:

public void Foo(List<Object> list, Object obj) {
  list.add(obj);
}

这看起来非常好,类型安全,直到你这样调用: / p>

This looks perfectly fine and type-safe until you call it like this:

List<Double> list_d;
String s;

Foo(list_d, s);

这也看起来类型安全,因为你作为调用者不一定知道Foo会去

Which also looks type-safe, because you as the caller don't necessarily know what Foo is going to do with its parameters.

因此,在这种情况下,你有两个看似安全的代码类型,它们最终都是类型不安全的。这很糟糕,因为它是隐藏的,因此很难避免,更难调试。

So in that case you have two seemingly type-safe bits of code, which together end up being type-unsafe. That's bad, because it's hidden and therefore hard to avoid and harder to debug.

这篇关于为什么List&lt; Number&gt;不是List&lt; Object&gt;的子类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 01:37