问题描述
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< Number>不是List< Object>的子类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!