[英]Why is no unchecked cast warning given when downcasting Throwable to Exception?
使用此代码:
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 不给出未经检查的强制转换警告?
Exception
扩展Throwable
,因此您不能将所有Throwable
转换为Exception
。
为什么 javac 不给出未经检查的强制转换警告?
因为没有涉及泛型。 我不认为“未经检查的演员表”意味着你认为它意味着什么。 它适用于以下情况:
List<?> list = getListFromSomewhere();
List<String> strings = (List<String>) list;
这是一个未经检查的强制转换,因为对List<String>
的强制转换并没有真正检查list
是否引用List<String>
......它不能这样做,因为在执行时没有这样的概念。
您目前从Throwable
到Exception
的转换只是一个普通的转换 - 如果cause
是对不是Exception
(或子类)的对象的引用,它将抛出ClassCastException
。
术语“未经检查的”警告具有误导性。 这并不意味着以任何方式取消检查警告。 术语“未检查”是指编译器和运行时系统没有足够的类型信息来执行确保类型安全所必需的所有类型检查。 从这个意义上说,某些操作是“未经检查的”。 来源
警告并不是说这个演员表可能会失败。 它是说,通过执行此转换,可能会导致其他类型错误。
Java 允许这种类型的转换,因为Throwable
可能是一个Exception
。
通常你会在它之前进行测试,例如:
if (cause != null) {
if (cause instanceof Exception) {
Exception exCause = (Exception) cause;
System.out.println(exCause);
}
}
这段代码非常好,不应该发出警告。 编译器不够聪明,无法在您的情况下发出警告,而在我的示例中未发出警告。
当向下转换(例如从Throwable
到Exception
)时,编译器不会也不应该发出警告。
失败的向下转换(例如,尝试将声明为Throwable
的Error
Throwable
为Exception
)只会导致ClassCastException
,就像取消引用null
会导致NPE
,访问超出范围的数组将导致ArrayIndexOutOfBoundsException
和所有其他 RuntimeExceptions。
尽管如此,这个转换还是安全的,因为在运行时 JVM 可以判断转换失败(与转换通用实例不同)。
Java 中有两种类型的转换 - 向上转换和向下转换。
Java 中的代码执行有两个阶段——编译和执行。
编译会检查诸如语法之类的内容,并确保没有任何明显的错误。
执行实际上是在执行代码,如果有问题,它会抛出异常。
你总是可以毫无错误地进行向上转换。
然而,低头是有风险的。 在两种情况下,向下转型可能会带来风险。 案例#1:例如,您将对象向下转换为字符串。 这可能有风险,因为并非所有对象都是字符串。 但是,编译器可以通过确保引用变量指向的对象是字符串来轻松检查这一点。 这适用于您的问题,因为您安全地向下转型,因此编译器很高兴。 案例#2:你有泛型。 在泛型的情况下,在编译期间,编译器不知道类型是什么,因此它不能确保转换会正常工作。 这是它会发出警告的时候。 如果转换不能正常工作,则在运行时将抛出 ClassCast 异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.