我今天遇到了这种奇怪的(在我看来)行为。拿这个简单的测试类:
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");
}
}
它的行为与您期望的一样,打印“对象列表”。但是如果你改变以下三行:
List<String> list = new ArrayList<String>();
list.add("");
list.add("");
你会得到“对象”。
我尝试了其他一些方法并获得了相同的结果。这是一个错误还是正常行为?如果这是正常的,有人可以解释原因吗?
感谢。
答案 0 :(得分:12)
这是正常行为。 List<String>
不是List<Object>
,因此method(Object)
是唯一适用的方法。
如果List<String>
是List<Object>
,您就可以违反类型安全,例如,将Integer
添加到List<String>
(并且不能由于类型擦除而在运行时捕获):
public void method(List<Object> o) {
o.add(new Integer(10));
}
另请注意,数组具有不同的行为 - String[]
是Object[]
,因为如果您尝试将错误的对象放入其中,则数组会知道其元素类型并抛出运行时异常。
答案 1 :(得分:6)
这是正常行为,因为当您使用泛型定义签名时,您指定一个类。 (除非您使用的是wildcards,否则链接会解释)...
所以List<String>
不是List<Object>
。不过,List<? extends Object>
是试一试。
答案 2 :(得分:1)
这是预期的 - 列表不是List<Object>
类型。要获得您期望使用的结果:
public void method(List<?> o)
作为外卡,这将与您的列表匹配。
答案 3 :(得分:0)
正如预期的那样,List<String>
不是List<Object>
,如另一个答案中所述。要获得所需的行为,您需要使用通配符:
public void method(List<? extends Object> o) { //or an unbounded wildcard List<?>
System.out.println("List of Objects");
}
答案 4 :(得分:0)
您需要了解java泛型。 List<String>
不是List<Object>
。
Any simple way to explain why I cannot do List<Animal> animals = new ArrayList<Dog>()?