简体   繁体   English

将null传递给java中的重载方法重载的变量是异常类型

[英]Passing null to overloaded methods in java | variables of overloaded are Exception type

I'm practicing some examples in Java. 我正在用Java练习一些例子。 The code looks like this: 代码如下所示:

public class NullPassing {
    public static void main(String[] args) {
        method1(null);
    }
    public static void method1(Exception e) {
        System.out.println(e);
    }
    public static void method1(ArithmeticException e) {
        System.out.println(e);
    }
}

I have few questions regarding this, 我对这个问题很少,

1) The above code executes and prints null by using method1(ArithmeticException e), Why isn't it using Exception(Since its tops the hierarchy) ? 1)上面的代码使用method1(ArithmeticException e)执行并打印null,为什么不使用Exception(因为它的顶层是层次结构)?

Guess: Is it because of more specific variable ArithmeticException specific compared to Exception . 猜猜:是否因为比Exception更具体的变量ArithmeticException If that's the case, why Question-2 如果是这样,为什么问题-2

2) By introducing the following method to the existing code, program shows compile time exception. 2)通过在现有代码中引入以下方法,程序显示编译时异常。 Why? 为什么?

public static void method1(NullPointerException e) {
    System.out.println(e);
}

Help me learn. 帮我学习 Thanks 谢谢

We have two candidates, 我们有两个候选人,

 public static void method1(Exception e) {
 }
 public static void method1(ArithmeticException e) {
 }

We pass a null and both methods accept nulls, so we choose the more specific one, ArithmeticException is an Exception but the opposite is not true, and hence ArithmeticException is more specific. 我们传递一个null并且两个方法都接受空值,所以我们选择更具体的一个, ArithmeticException是一个Exception但相反的不是真的,因此ArithmeticException更具体。

Now we have three candidates 现在我们有三名候选人

public static void method1(Exception e) {
}
public static void method1(ArithmeticException e) {
}
public static void method1(NullPointerException e) {
}

The first one is out of the equation because there are more specific ones, so we are left with two candidates, one that takes NullPointerException and the other takes ArithmeticException , both are on the same level, and hence we have an ambiguous call. 第一个不在等式中,因为有更多特定的,所以我们留下两个候选,一个采用NullPointerException ,另一个采用ArithmeticException ,两者都在同一级别,因此我们有一个模糊的调用。

Your answer to 1 is correct. 你对1的回答是正确的。 Given the choice where two or more overloads are candidate, and one of them is more specific than all of the others, the most specific one is chosen. 如果选择两个或多个重载是候选的,并且其中一个比其他所有重载更具体,则选择最具体的重载。

The JLS says this ( Section 15.12.2.5 ): JLS说明了这一点( 第15.12.2.5节 ):

If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. 如果多个成员方法都可访问并适用于方法调用,则必须选择一个为运行时方法调度提供描述符。 The Java programming language uses the rule that the most specific method is chosen. Java编程语言使用选择最具体方法的规则。 The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time error. 非正式的直觉是,如果第一个方法处理的任何调用都可以传递给另一个没有编译时错误的调用,那么一个方法比另一个方法更具体。

(It then explains formally what "more specific" means.) (然后它正式解释了“更具体”的含义。)


In your second case / question, you have this: 在你的第二个案例/问题中,你有这个:

public class NullPassing {
    public static void main(String[] args) {
        method1(null);
    }
    public static void method1(Exception e) {
        System.out.println(e);
    }
    public static void method1(ArithmeticException e) {
        System.out.println(e);
    }
    public static void method1(NullPointerException e) {
        System.out.println(e);
    }  
}

Now we have three candidates (methods that are "accessible and applicable"). 现在我们有三个候选人(“可访问和适用”的方法)。 The first one is less specific than the other two, but neither of the two remaining candidates is more specific than the other. 第一个比其他两个更不具体,但剩下的两个候选人中没有一个比另一个更具体。 Therefore this is a compilation error. 因此,这是一个编译错误。

Obviously, you can disambiguate the call by casting the null ; 显然,你可以通过转换null消除歧义 ; eg 例如

  method1((NullPointerException)null)

1. Why does it use ArithmeticException? 1.为什么使用ArithmeticException?

Java tries to select the most specific overloaded method for any object type. Java尝试为任何对象类型选择最具体的重载方法。 The null object is of type "[special null type]" which is a subtype of all non-primitive type; null对象的类型为“[special null type]”,它是所有非基本类型的子类型; therefore the most specific subtype is ArithmeticException . 因此,最具体的子类型是ArithmeticException

For more information on how the Java compiler does resolve overloading, see this answer: https://stackoverflow.com/a/7199189/112964 有关Java编译器如何解决重载的更多信息,请参阅以下答案: https//stackoverflow.com/a/7199189/112964

2. Why does the program not compile if you add a NullPointerException? 2.如果添加NullPointerException,为什么程序不能编译?

Once you have serveral overloads that are not in the same inheritance hierarchy, the Java compiler gets more than one possible candidate for the most specific overload: both method1(NullPointerException) and method1(ArithmeticException) are the most specific candidates. 一旦你有serveral的重载不在同一个继承层次,Java编译器得到不止一个可能的候选人的最具体的过载: 两个 method1(NullPointerException)method1(ArithmeticException)是最具体人选。 Therefore, you must tell the compiler what you actually want by casting null to the overloaded type: eg method1((NullPointerException)null) . 因此,您必须通过将null转换为重载类型来告诉编译器您实际需要什么:例如method1((NullPointerException)null)

For more information about ambiguous overloads, see https://stackoverflow.com/a/5229890/112964 有关模糊重载的更多信息,请参阅https://stackoverflow.com/a/5229890/112964

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM