解析带有省略的varargs参数的Java方法

  • 本文关键字:varargs 参数 Java 方法 java
  • 更新时间 :
  • 英文 :


我有以下类的定义:

class A {
String foo(Object par) {
     return par.toString();
  }
}
class B extends A {
 static String foo(String par, Object ... pars) {
   return par.toString();
 }
}

如果我执行类似B.foo("hello");的调用,那么我会得到一个编译错误

错误:不能从静态上下文引用非静态方法foo(Object)

当然,B.foo("hello", (Object[])null);工作得很好。然而,如果我将虚拟方法foo重命名为foo1,那么编译错误就会消失。这意味着静态方法调用的第一个变体仍然有效,但编译器会首先尝试匹配虚拟签名。有人能从Java语言规范文档中提供正确的行为解释吗?

JLS#115.2.2中定义了方法解析算法。实质上,没有varargs的方法优先于有varargs(强调矿)的方法:

第一阶段(§15.12.2.2)执行重载解析,而不允许装箱或取消装箱转换,或使用变量arity方法调用。如果在该阶段期间没有找到适用的方法,则处理继续到第二阶段。

正如JLS中所解释的,它是这样做的"以确保与Java SE 5.0之前的Java编程语言版本的兼容性"。

A.foo不是静态的,而B.foo是.

调用B.foo("Hello")是一个错误,因为继承的A.foo方法不是静态的。你说正在工作的电话可能向你发出了警告?

最新更新