gpt4 book ai didi

java - 多异常捕获子句中异常的静态类型是什么?

转载 作者:行者123 更新时间:2023-12-03 11:19:27 26 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





In a Java 7 multicatch block what is the type of the caught exception?

(2 个回答)


1年前关闭。




在此代码示例中,e 的静态类型是什么?在 catch block 中?

try {
....
} catch(IOException | NumberFormatException e) {
//what's the static type of e in here? Is it Exception?
System.out.println(e.getClass());
}
似乎有效 Exception ,但是当我在 IDE 中将鼠标悬停在它上面时,它会显示 IOException | NumberFormatException .这是仅适用于 catch block 中的多个异常的特殊类型,还是泛化到其他类型?

最佳答案

TL;DR: 静态类型是最近的公共(public)父类(super class)。

Java Language Specification , 部分 14.20. The try statement ,说:

An exception parameter may denote its type as either a single class type or a union of two or more class types (called alternatives). The alternatives of a union are syntactically separated by |.

A catch clause whose exception parameter is denoted as a single class type is called a uni-catch clause.

A catch clause whose exception parameter is denoted as a union of types is called a multi-catch clause.


The declared type of an exception parameter that denotes its type with a single class type is that class type.

The declared type of an exception parameter that denotes its type as a union with alternatives D1 | D2 | ... | Dn is lub(D1, D2, ..., Dn).


因此,它基本上被称为“联合类型”,并且在语言的其他地方不存在。

更新
有效类型是 最接近的普通父类(super class)型的联合 (类和/或接口(interface)),即您可以调用所有替代方案通用的任何方法。
下面的代码说明了以下几点:
  • 由于这两个异常(exception)都扩展了 SuperException ,您可以调用SuperException方法。
  • 由于两个异常都实现了接口(interface) Foo ,您可以调用Foo方法。
  • 有效类型不是SuperException , 因为那时你不能调用 Foo方法,它不是 Foo , 因为那时你不能调用 SuperException方法。
  • 有效类型实际上是最接近的常见父类(super class)型的联合,这实际上意味着所有常见的父类(super class)型。

  • try {
    // some code throwing the exceptions
    } catch (SubException1 | SubException2 e) {
    e.methodInSuper(); // you can call the SuperException method
    e.foo(); // you can call the Foo method
    }
    interface Foo {
    void foo();
    }
    class SuperException extends Exception {
    public void methodInSuper() {
    // code here
    }
    }
    class SubException1 extends SuperException implements Foo {
    @Override
    public void foo() {
    // code here
    }
    }
    class SubException2 extends SuperException implements Foo {
    @Override
    public void foo() {
    // code here
    }
    }

    更新 2
    要回答确切的问题“异常的静态类型是什么?”,我们需要查看字节码。
    上述代码的catch子句的字节码为:
            34: astore_1
    35: aload_1
    36: invokevirtual #33 // Method SuperException.methodInSuper:()V
    39: aload_1
    40: checkcast #38 // class Foo
    43: invokeinterface #40, 1 // InterfaceMethod Foo.foo:()V
    48: return
    Exception table:
    from to target type
    0 34 34 Class SubException1
    0 34 34 Class SubException2
    如您所见,单 catch子句注册了 2 个要捕获的异常,将它们指向同一个代码块。调用 SuperException.methodInSuper()直接完成。调用 Foo.foo()在转换为 Foo 后完成.编译后的代码可以认为等同于以下代码,除了它只捕获 2 个子异常:
    } catch (SuperException e) { // only catch SubException1 and SubException2
    e.methodInSuper();
    ((Foo) e).foo();
    }
    结论:静态类型是 最近的普通父类(super class) .该父类(super class)未定义的任何其他公共(public)接口(interface)都由编译器使用强制转换静默处理。

    关于java - 多异常捕获子句中异常的静态类型是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64575605/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com