[英]Strange behavior when overloading methods in Java
I came across this weird (in my opinion) behavior today. 我今天遇到了这种奇怪的(在我看来)行为。 Take this simple Test class:
拿这个简单的Test类:
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.run();
}
private void run() {
List<Object> list = new ArrayList<Object>();
list.add(new Object());
list.add(new Object());
method(list);
}
public void method(Object o) {
System.out.println("Object");
}
public void method(List<Object> o) {
System.out.println("List of Objects");
}
}
It behaves the way you expect, printing "List of Objects". 它的行为与您期望的一样,打印“对象列表”。 But if you change the following three lines:
但是如果你改变以下三行:
List<String> list = new ArrayList<String>();
list.add("");
list.add("");
you will get "Object" instead. 你会得到“对象”。
I tried this a few other ways and got the same result. 我尝试了其他一些方法并获得了相同的结果。 Is this a bug or is it a normal behavior?
这是一个错误还是正常行为? And if it is normal, can someone explain why?
如果这是正常的,有人可以解释为什么吗?
Thanks. 谢谢。
It's a normal behaviour. 这是正常的行为。
List<String>
is not a List<Object>
, so method(Object)
is the only applicable method. List<String>
不是List<Object>
,因此method(Object)
是唯一适用的方法。
If List<String>
were a List<Object>
, you would be able to violate type safety, for example, by adding Integer
to the List<String>
(and it can't be caught at runtime due to type erasure): 如果
List<String>
是List<Object>
,则可以违反类型安全性,例如,通过将Integer
添加到List<String>
(并且由于类型擦除而无法在运行时捕获):
public void method(List<Object> o) {
o.add(new Integer(10));
}
Also note that arrays have a different behaviour - String[]
is an Object[]
, because array knows its element type and throws a runtime exception if you try to put a wrong object into it. 另请注意,数组具有不同的行为 -
String[]
是Object[]
,因为如果您尝试将错误的对象放入其中,则array知道其元素类型并抛出运行时异常。
This is normal behaviour, because when you define a signature with generics, you specify a single class. 这是正常行为,因为当您使用泛型定义签名时,您可以指定单个类。 (Unless you use wildcards , which you haven't, the link explains)...
(除非您使用通配符 ,否则链接会解释)...
So List<String>
is not a List<Object>
. 因此
List<String>
不是List<Object>
。 It is, however a List<? extends Object>
它是一个
List<? extends Object>
List<? extends Object>
- give it a try and see. List<? extends Object>
- 试一试看看。
Well this is expected - the list is not of type List<Object>
. 这是预期的 - 列表不是
List<Object>
类型。 To get the results you are expecting use: 要获得您期望使用的结果:
public void method(List<?> o)
as a wild card, this will match your list. 作为外卡,这将匹配您的列表。
As expected because List<String>
is not a List<Object>
as stated in the other answer. 正如所料,因为
List<String>
不是List<Object>
如另一个答案中所述。 To obtain the desired behavior, you need to use a wildcard: 要获得所需的行为,您需要使用通配符:
public void method(List<? extends Object> o) { //or an unbounded wildcard List<?>
System.out.println("List of Objects");
}
You need to understand java generics. 你需要了解java泛型。
List<String>
is not List<Object>
. List<String>
不是List<Object>
。 Any simple way to explain why I cannot do List<Animal> animals = new ArrayList<Dog>()? 任何简单的方法来解释为什么我不能做List <Animal> animals = new ArrayList <Dog>()?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.