使用此代码:
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
。
答案 0 :(得分:10)
为什么javac没有给出未经检查的演员警告?
因为没有涉及泛型。我不认为"未选中演员"意味着你的意思。它适用于以下情况:
List<?> list = getListFromSomewhere();
List<String> strings = (List<String>) list;
这是一项未经检查的演员,因为List<String>
的演员并没有真正检查list
是否引用了List<String>
......它无法做到,因为在执行时没有这样的概念。
目前从Throwable
到Exception
的演员阵容只是普通演员阵容 - 如果ClassCastException
是参考,它会抛出cause
到不 Exception
(或子类)的对象。
答案 1 :(得分:1)
术语&#34;未经检查&#34;警告是误导。这并不意味着 警告是以任何方式取消选中的。术语&#34;未经检查&#34;是指 事实上,编译器和运行时系统没有足够的类型 用于执行必要的所有类型检查的信息 确保类型安全。从这个意义上说,某些操作是未经检查的&#34;。 Source
警告并不是说此演员表可能会失败。它说,通过这种演员表,可能会出现其他类型的错误。
答案 2 :(得分:0)
Java允许这种类型的强制转换,因为Throwable
可能是Exception
。
通常你会在它之前进行测试,例如:
if (cause != null) {
if (cause instanceof Exception) {
Exception exCause = (Exception) cause;
System.out.println(exCause);
}
}
这段代码非常好,不应该发出警告。编译器不够聪明,不能在您的情况下发出警告,并且在我的示例中没有给出警告。
答案 3 :(得分:0)
当向下转换时(例如从Throwable
到Exception
),编译器不且 不应该 < / strong>发出警告。
失败的向下广播(例如,尝试将Error
声明为Throwable
转换为Exception
)只会导致ClassCastException
,就像取消引用null
一样导致NPE
,访问超出边界的数组将导致ArrayIndexOutOfBoundsException
和所有其他RuntimeExceptions。
但是,这个演员是安全的,因为在运行时JVM可以告诉演员表失败(与演员通用实例不同)。
答案 4 :(得分:0)
Java中有两种类型的强制类型转换:向上转换和向下转换。
Java中有两个代码执行阶段-编译和执行。
编译检查语法等内容,并确保没有明显的错误。
执行实际上会执行代码,如果出现错误,则会引发异常。
您始终可以进行向上转换,而不会出现任何错误。
但是,向下转换可能会有风险。有两种类型的垂降风险很大。案例1:例如,您将一个对象下放为字符串。这可能会有风险,因为并非所有对象都是字符串。但是,编译器可以通过确保引用变量指向的对象是String来轻松地检查这一点。这适用于您的问题,因为您安全地向下转换,因此编译器感到满意。 情况2:您有泛型。对于泛型,在编译期间,编译器不知道类型是什么,因此无法确保强制转换会正常工作。这是时候它会发出警告。如果强制转换无法正常进行,则会在运行时抛出ClassCast异常。