方法重载null参数

Pha*_*ani 128 java oop null overloading

我添加了三个带参数的方法:

public static  void doSomething(Object obj) {
    System.out.println("Object called");
}

public static  void doSomething(char[] obj) {
    System.out.println("Array called");
}

public static  void doSomething(Integer obj) {
    System.out.println("Integer called");
}
Run Code Online (Sandbox Code Playgroud)

当我调用时doSomething(null),编译器会将错误视为模糊方法.所以是问题,因为Integerchar[]方法,或IntegerObject方法呢?

Joa*_*uer 204

Java将始终尝试使用可用方法的最具体适用版本(请参阅JLS§15.12.2).

Object,char[]并且Integer都可以null作为有效值.因此,所有3个版本都适用,因此Java必须找到最具体的版本.

由于Object是超类型char[],因此数组版本比Object-version 更具体.因此,如果仅存在这两种方法,char[]则将选择版本.

当两个char[]Integer版本可用,则两者都是比更具体的Object,但没有一个比另一个更具体,所以Java不能决定调用哪一个.在这种情况下,您必须通过将参数强制转换为适当的类型来明确提及要调用的那个.

请注意,在实践中,这个问题比人们想象的要少得多.这样做的原因是它只发生在您使用null或者使用非特定类型的变量(例如Object)显式调用方法时.

相反,以下调用将是完全明确的:

char[] x = null;
doSomething(x);
Run Code Online (Sandbox Code Playgroud)

虽然您仍在传递值null,但Java确切地知道要调用哪个方法,因为它会考虑变量的类型.

  • 我很确定这些规则对于Java 1.1以来的所有规则都是相同的(显然除了泛型之外). (2认同)

jmg*_*jmg 40

当使用null参数调用时,这三种方法中的每一对本身都是模糊的.因为每个参数类型都是引用类型.

以下是使用null调用您的一个特定方法的三种方法.

doSomething( (Object) null);
doSomething( (Integer) null);
doSomething( (char[]) null);
Run Code Online (Sandbox Code Playgroud)

如果你真的计划用null参数调用这些方法,我建议你删除这种歧义.这样的设计将来会引发错误.

  • 只有`Integer`-`char[]`对是不明确的,因为在其他两种情况下,Java编译器可以选择最具体的选择,就像@JoachimSauer描述的那样。 (2认同)
  • @kajacx:OP 最初的问题是关于使用 `null` 作为参数调用这些方法。在这个前提下,所有三对都是不明确的。对于一般情况,我同意只有 `Integer - char[]` 对是不明确的。 (2认同)

Lar*_*ski 6

null是三种类型中任何一种的有效值;所以编译器无法决定使用哪个函数。使用类似doSomething((Object)null)doSomething((Integer)null)代替的东西。

  • Java 数组也是对象。 (3认同)