为什么以下代码不会导致"未经检查的强制转换"警告?

Zhu*_* Li 5 java unchecked-cast

我认为这(String)x是一个未经检查的演员,但编译器没有给出任何警告.为什么会这样?

public static void main(String[] args) {
        Object x=new Object();
        String y=(String)x;
    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

我认为这(String)x是一个未经检查的演员

不,这不对.它在执行时检查 - 如果转换无效,它将抛出异常.

未经检查的强制转换是关于看起来像是要检查的强制转换,但实际上并不会因为类型擦除而检查您期望的所有内容.例如:

List<String> strings = new ArrayList<>();
Object mystery = strings;
List<Integer> integers = (List<Integer>) mystery;
integers.add(0); // Works
String x = strings.get(0); // Bang! Implicit cast fails
Run Code Online (Sandbox Code Playgroud)

这里(List<Integer>) mystery只有对象所mystery引用的检查的强制转换是List- 而不是a List<Integer>.检查该Integer部分,因为在执行时没有这样的概念.List<Integer>

所以在我们的例子中,该演员在没有"真实"检查的情况下成功 - 并且add调用工作正常,因为这只是Object[]Integer元素填充.最后一行失败,因为调用get()隐式执行强制转换.

就VM而言,示例代码是有效的:

List strings = new ArrayList();
Object mystery = strings;
List integers = (List) mystery;
integers.add(0);
String x = (String) strings.get(0);
Run Code Online (Sandbox Code Playgroud)