当前位置: 首页 > 知识库问答 >
问题:

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

孔鸿宝
2023-03-14

我正在Java中练习一些例子。代码如下所示:

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);
    }
}

关于这一点,我没有什么问题,

1) 上面的代码使用method1(算术异常e)执行并打印null,为什么不使用异常(因为它位于层次结构的顶部)?

猜测:这是因为与异常相比,算术异常更加具体。如果是这样,为什么要问第二个问题

2) 通过在现有代码中引入以下方法,程序显示编译时异常。为什么?

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

帮助我学习。谢谢

共有3个答案

闾丘朗
2023-03-14

Java尝试为任何对象类型选择最具体的重载方法。null对象的类型为“[特殊null类型]”,它是所有非基元类型的子类型;因此,最具体的子类型是算术异常。

有关Java编译器如何解决重载的更多信息,请参阅以下答案:https://stackoverflow.com/a/7199189/112964

一旦您有了不在同一继承层次结构中的多个重载,Java编译器将获得多个最特定重载的可能候选对象:最特定的候选对象是method1(NullPointerException)和method1(ArrithmeticException)。因此,您必须通过将null强制转换为重载类型来告诉编译器您实际需要什么:例如method1((NullPointerException)null)

有关不明确重载的详细信息,请参阅https://stackoverflow.com/a/5229890/112964

元昊苍
2023-03-14

我们有两个候选人,

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

我们传递一个null,两个方法都接受null,所以我们选择更具体的一个,ArithmeticException是一个异常,但相反的不是真的,因此,ArithmeticException更具体。

现在我们有三位候选人

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

第一个是等式之外的,因为还有更具体的,所以我们剩下两个候选者,一个接受NullPointerException,另一个接受ArtihmeticException,两者都处于同一级别,因此我们有一个不明确的调用。

饶滨海
2023-03-14

你对1的回答是正确的。给定两个或多个重载是候选的选择,并且其中一个比所有其他重载都更具体,则选择最具体的一个。

JLS这样说(第15.12.2.5节):

如果一个方法调用可以访问并应用多个成员方法,则需要选择一个成员方法来为运行时方法调度提供描述符。Java编程语言使用的规则是选择最具体的方法。非正式的直觉是,如果第一个方法处理的任何调用都可以传递给另一个方法而不会出现编译时错误,那么一个方法比另一个方法更具体。

(然后它正式解释了“更具体”的含义。)

在第二个案例/问题中,您有:

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);
    }  
}

现在我们有三个候选者(“可访问且适用”的方法)。第一个不如其他两个具体,但剩下的两个候选者都没有比另一个更具体。因此这是一个编译错误。

显然,您可以通过强制转换null来消除调用的歧义;例如

  method1((NullPointerException)null)
 类似资料:
  • 我在一个类中重载了以下2个方法: 当我调用方法testMethod时,它会打印“String”。 当我再添加一个重载方法时: 它抛给我编译器错误:是矛盾的。 当我用null调用方法时,所有这些都会发生 我的问题是: 为什么它打印字符串而不是对象? 为什么添加第三种方法会出现编译错误?

  • 我有以下代码: 我知道对于1和3,它打印“2”,因为调用了最特定的参数类型。但无法理解为什么2打印“2”。

  • 在以下程序中: 输出为“str”,有人能解释一下为什么要打印str吗?我无法理解这一点。

  • 问题内容: 假设我有一个Point带有x和y参数的不可变类,以及一个add定义如下的方法: 由于它是不可变的,因此它返回一个新的Point。这一切都很好,直到我们有了一个扩展Point并重新定义的类add。 我们必须编写新的定义,因为否则将返回addon的方法,这是不好的。但是现在,这在大多数语言中都行不通,因为我们正在压倒一切,但我们只是在对返回类型进行歧义处理。语言不允许您只对返回类型进行歧义

  • 可能重复:NULL参数的方法重载 以下代码编译并运行良好。 在此代码中,要调用的方法是接受字符串类型参数的方法 医生说。 如果多个成员方法既可访问又适用于方法调用,则需要选择一个来为运行时方法调度提供描述符。Java编程语言使用选择最具体方法的规则。 但我不明白,当代码中接受原语int参数的方法之一被修改为接受包装器类型Integer的参数时,例如, 发出编译时错误。 对temp的引用不明确,me

  • 问题内容: 我有类似下面的代码: 但是,该变量未在ActionListener类的范围内定义。如何传递变量? 问题答案: 除了Hovercraft的答案外,您还应注意,您不会被迫对侦听器使用匿名类。气垫船的答案代码类似于以下代码: