空值被视为对象或数组。

4
public class Test
 {

    public Test(Object o) {
        System.out.println("object");
    }

    public Test(int[] o) {
        System.out.println("array");
    }

    public static void main(String[] args) {
        new Test(null);
    }
}

输出:

array

能否有人解释一下这背后的原因?


相关阅读:选择最具体的方法 - JonK
5个回答

7
规则是: 调用最具体的方法。 在这种情况下,接收int []的方法比接收java.lang.Object参数的方法更具体。

这里是Java官方文档,引用了这个案例。看一下15.2.2部分。引用一个有趣的部分(第15.2.2.5节):

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

非正式的直觉是,如果第一个方法处理的任何调用可以传递给另一个方法而不会出现编译时类型错误,则一个方法比另一个方法更具体。

还有另一个:

可能没有最具体的方法,因为存在两个或多个最大限度具体的方法。在这种情况下: 如果所有最大限度具体的方法具有重写等效签名(§8.4.2),则: 如果最大限度具体的方法中恰好有一个未声明为抽象,则它是最具体的方法。 否则,如果所有最大限度具体的方法都声明为抽象,并且所有最大限度具体的方法的擦除(§4.6)具有相同的签名,则在最大限度具体的方法子集中任意选择最具体的返回类型。但是,只有在每个最大限度具体方法的throws子句中声明了该异常或其擦除时,才认为最具体的方法会引发已检查的异常。否则,我们说该方法调用不明确,并且会发生编译时错误。

只是为了完整性:为什么int[]Object更具体? - user1907906
3
@LutzHorn 因为 java.lang.Object 根据定义是所有 Java 类型的根源,因此它是可能的最不具体的类型(所有东西都扩展自 java.lang.Object)。 - JBA
@LutzHorn 注意:诸如int、long等原始类型当然是另一回事,因此上述“everything”在此上下文中都是错误的;) - JBA

1
正如Pablo的回答所建议的那样,将调用最具体/最不通用的方法。实际上,检查类层次结构中的类级别以决定调用哪个方法。调用较低类级别的方法。
如果2个类处于同一级别,则会出现编译时错误,指出“模棱两可的方法调用”,就像下面的情况一样。
public class Sample {
void someMethod(Object o) {
    System.out.println("object");
}

void someMethod(String s) {
    System.out.println("String");
}

void someMethod(int[] o) {
    System.out.println("int[]");
}

public static void main(String[] args) {
    new Sample().someMethod(null); // error ambiguous call both array and String are direct children of Object
}

案例-2:证明具有较低类级别的方法将被调用。
public class Sample {
void someMethod(Object o) {
    System.out.println("object");
}

void someMethod(OutputStream os) {
    System.out.println("OutputStream");
}

void someMethod(FileOutputStream fos) {
    System.out.println("FileOutputStream");
}

public static void main(String[] args) {
    new Sample().someMethod(null);
}

}

O/P :FileOutputStream

由于FileOutputStream是OutputStream的子类,而OutputStream又是Object类的子类(FileOutputStream同时也是OutputStream和Object类的子类)。因此编译器在解析方法调用时会按照以下顺序:Object --> OutputStream --> FileOutputStream


1

通常情况下,子类优先于父类。如果您想调用Object类,则可以执行以下操作:

new goFuncTest((Object) null);

0

将Null升级为Array优于将其转换为Object。Object在层次结构的顶部,而Array最接近Null。

这就像将byte升级为int一样。


0

方法调用中的黄金法则是优先考虑子类。由于Object是所有类的父类,并且null可以分配给任何类型的对象实例变量,因此它将首先匹配任何Java类型(当然是Object的子类),然后才是超级父类即Object。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接