5

使用此代码:

public class DowncastTest {
    public static void main(String[] args) {
        try {
            System.out.println(1);
        } catch (Exception ex) {
            Throwable cause = ex.getCause();
            if (cause != null) {
                Exception exCause = (Exception)cause;
                System.out.println(exCause);
            }
        }
    }
}

为什么 javac 不给出未经检查的强制转换警告?

Exceptionextends Throwable,因此您不能只将所有Throwables 转换为Exception.

4

5 回答 5

10

为什么 javac 不给出未经检查的强制转换警告?

因为不涉及泛型。我不认为“未经检查的演员表”意味着您认为的意思。它适用于以下情况:

List<?> list = getListFromSomewhere();
List<String> strings = (List<String>) list;

这是一个未经检查的强制转换,因为强制转换List<String>并没有真正检查是否list引用了List<String>... 它不能这样做,因为在执行时没有这样的概念。

你现在从Throwableto得到的转换Exception只是一个普通的转换——它会抛出一个ClassCastExceptionifcause是对一个不是(或子类)对象的引用Exception

于 2014-07-22T14:55:42.263 回答
1

术语“未经检查的”警告具有误导性。这并不意味着以任何方式未检查警告。术语“未检查”是指编译器和运行时系统没有足够的类型信息来执行确保类型安全所必需的所有类型检查。从这个意义上说,某些操作是“未经检查的”。 资源

警告并不是说这个演员可能会失败。也就是说,通过执行此转换,结果可能会出现其他类型错误。

于 2014-07-22T14:58:28.427 回答
0

Java 允许这种类型的强制转换,因为 aThrowable可能是Exception.

通常,您会在它之前进行测试,例如:

    if (cause != null) {
        if (cause instanceof Exception) {
            Exception exCause = (Exception) cause;
            System.out.println(exCause);
        }
    }

这段代码非常好,不应该给出警告。编译器不够聪明,无法在您的情况下发出警告,在我的示例中也不发出警告。

于 2014-07-22T14:55:38.783 回答
0

当向下转换(例如 from Throwableto Exception)编译器不会也不应该发出警告。

失败的向下转换(例如,尝试将Error声明的转换为Throwableto Exception)将简单地导致 to ClassCastException,就像取消引用null将导致NPE,超出边界访问数组将导致ArrayIndexOutOfBoundsException以及所有其他 RuntimeExceptions。

尽管如此,这种强制转换是安全的,因为在运行时 JVM 可以判断强制转换失败(与强制转换通用实例不同)。

于 2014-07-22T15:13:01.457 回答
0

Java中有两种类型的强制转换——向上转换和向下转换。

Java中代码执行有两个阶段——编译和执行。

编译会检查语法等内容并确保没有任何明显的错误。

Execution 实际上是执行代码,如果出现问题,它会抛出异常。

您始终可以进行向上转换而不会出现任何错误。

然而,向下转型可能是有风险的。当向下转换可能有风险时,有两种情况。案例 #1:例如,您将对象向下转换为字符串。这可能是有风险的,因为并非所有对象都是字符串。但是,编译器可以通过确保引用变量指向的对象是字符串来轻松检查这一点。这适用于您的问题,因为您安全地向下转换,因此编译器很高兴。案例#2:你有泛型。在泛型的情况下,在编译期间,编译器不知道类型是什么,因此它不能确保转换能够正常工作。这是它会发出警告的时候。如果转换不能正常工作,则会在运行时抛出 ClassCast 异常。

于 2020-07-13T18:31:10.303 回答