当参数是文字空值时,如何选择重载方法?

zak*_*yed 97 java overloading

我在测验中遇到了这个问题,

public class MoneyCalc {

   public void method(Object o) {
      System.out.println("Object Verion");
   }

   public void method(String s) {
      System.out.println("String Version");
   }

   public static void main(String args[]) {
      MoneyCalc question = new MoneyCalc();
      question.method(null);
   }
}
Run Code Online (Sandbox Code Playgroud)

该程序的输出是"String Version".但是我无法理解为什么将null传递给重载方法会选择字符串版本.null是一个String变量,指向什么?

但是当代码更改为时,

public class MoneyCalc {

   public void method(StringBuffer sb) {
      System.out.println("StringBuffer Verion");
   }

   public void method(String s) {
      System.out.println("String Version");
   }

   public static void main(String args[]) {
      MoneyCalc question = new MoneyCalc();
      question.method(null);
   }
}
Run Code Online (Sandbox Code Playgroud)

它给出了一个编译错误,说"方法方法(StringBuffer)对于MoneyCalc类型是不明确的"

Jon*_*eet 102

null是一个String变量,指向什么?

可以将空引用转换为任何类类型的表达式.所以在这种情况下String,这很好:

String x = null;
Run Code Online (Sandbox Code Playgroud)

String选择此处的重载是因为Java编译器根据JLS的第15.12.2.5节选择最具体的重载.特别是:

非正式的直觉是,如果第一个方法处理的任何调用都可以传递给另一个没有编译时类型错误的调用,那么一个方法比另一个方法更具体.

在第二种情况下,两种方法仍然适用,但既不是String也不StringBuffer比另一种更具体,因此两种方法都不比另一种方法更具体,因此编译器错误.

  • 因为`Object`可以采用任何类型并将其包装在`Object`中,而`String`只能采用`String`.在这种情况下,`String`比`Object`类型更具体. (11认同)
  • @zakSyed如果你被问到什么是更专业的"字符串"或"对象",你会怎么说?显然是"字符串",对吧?如果有人问:什么是更专业的"String"或"StringBuffer"?没有答案,它们都是正交专业,你如何在它们之间做出选择?然后你必须明确你想要哪一个(即通过转换你的空引用`question.method((String)null)`) (9认同)
  • String过载如何比Object过载更具体? (3认同)
  • @JonH"null"是引用类型,如果其中一个方法接收基本类型作为参数(即int),则在选择正确的方法来调用null类型的引用时,编译器甚至不会考虑它.如果用"Int"表示java.lang.Integer或者你的意思是原始类型int,那就太令人困惑了. (3认同)

Edw*_*rzo 9

此外,JLS 3.10.7还声明"null"是"null类型"的文字值.因此存在一种称为"null"的类型.

稍后,JLS 4.1声明存在一个无法声明变量的null类型,但您只能通过null文本使用它.后来它说:

null引用总是可以进行任何引用类型的扩展引用转换.

为什么编译器选择将它扩展为String可能会在Jon的答案中解释.

  • @ xavierm02当然可以.您可以使用任何其他类型的方法在Java中重载方法.尽管如此,这与问题或我的答案无关. (4认同)
  • @ xavierm02在Java语言规范中没有提到它.您能否引用您的参考资料,以便我们所有人都可以验证您的申请? (2认同)