【问题标题】:When passing null as argument to overloaded varargs method(Object... o) and non-varargs method(Object o), why varargs method is executed? [duplicate]将 null 作为参数传递给重载的可变参数方法(Object...o)和非可变参数方法(Object o)时,为什么要执行可变参数方法? [复制]
【发布时间】:2019-01-14 21:58:55
【问题描述】:

例如,一个类包含两个方法,

public void find(Object id);
public void find(Object... ids);

当我调用find(null)时,为什么jvm实际上执行了最后一个?

Calling Java varargs method with single null argument? 接受的答案中,我们可以读到

Java 不知道它应该是什么类型。它可以是一个空对象,也可以是一个空对象数组。 对于单个参数,它假定为后者。”

但这仍然无法解释。谁能提供更多信息,例如语言规范?

【问题讨论】:

  • 因为Object[]Object 更具体。见JLS §15.12.2
  • @apangin 您应该将其发布为答案
  • 不是答案——但定义 find(Object) 有什么意义吗?据推测,单参数实现与使用单个参数的可变参数实现产生相同的结果。还是有一个专门针对单个 arg 的实现更有效?
  • @another-dave 如果我没记错的话,效率是为什么除了List.of​(E... elements) 我们还有List.of(E e) List.of(E e1, E e2) ...直到List.of([..], E e9, E e10)

标签: java jvm


【解决方案1】:

Object[] 是比 Object 更具体的类型。

根据JLS §15.12.2

如果多个成员方法既可访问又适用于 方法调用,需要选择一个来提供 运行时方法分派的描述符。 Java 编程 语言使用选择最具体方法的规则。

非正式的直觉是一种方法比 如果可以传递第一个方法处理的任何调用,则另一个 在没有编译时错误的情况下转到另一个。

同一章也有一个关于所讨论情况的例子。

[...] 在 第一阶段。例如,在一个类中声明 m(Object...) 已经声明 m(Object) 导致不再选择 m(Object) 一些调用表达式(如 m(null)),因为 m(Object[]) 更多 具体的。

【讨论】:

  • 值得一提的是,JVM 认为 Object[] 比 Object 更具体,因为 Object 是任何数组类型的超类型。
  • @Pshemo ...以及可变参数和数组之间的历史关系。如果可变参数不是数组,我们就没有问题。但既然是这样,我们就必须保持与引入可变参数之前存在的重载解析规则的兼容性。
猜你喜欢
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多