在Java中重载方法时的奇怪行为

Strange behavior when overloading methods in Java

我今天遇到了这种奇怪的行为(在我看来)。参加这个简单的测试课程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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");
}
}

它按照您期望的方式运行,打印"对象列表"。但如果您更改以下三行:

1
2
3
List<String> list = new ArrayList<String>();
list.add("");
list.add("");

你将得到"对象"。

我尝试了其他一些方法,得到了同样的结果。这是错误还是正常行为?如果这是正常的,有人能解释为什么吗?

谢谢。


这是正常的行为。List不是List,因此method(Object)是唯一适用的方法。

如果ListList的话,您就可能违反类型安全,例如,将Integer添加到List中(并且由于类型擦除而无法在运行时捕获):

1
2
3
public void method(List<Object> o) {
    o.add(new Integer(10));
}

另外请注意,数组有不同的行为——String[]Object[],因为数组知道它的元素类型,并且如果试图将错误的对象放入其中,就会抛出运行时异常。


这是正常的行为,因为当您用泛型定义签名时,您指定了一个类。(除非您使用通配符,而您没有使用通配符,否则链接将解释)……

所以List不是List。不过,它是一个List—试试看。


好吧,这是意料之中的——这个列表不是List类型。要获得预期使用的结果,请执行以下操作:

1
public void method(List<?> o)

作为外卡,这将匹配您的列表。


您需要了解Java泛型。List不是List。有什么简单的方法可以解释为什么我不能做listanimals=new arraylist()?


正如预期的那样,因为List不是另一个答案中所述的List。要获得所需的行为,需要使用通配符:

1
2
3
public void method(List<? extends Object> o) { //or an unbounded wildcard List<?>
    System.out.println("List of Objects");
}

也见

  • Java语言指南/泛型/更有趣的通配符