public class InterfaceCasting {
private static class A{}
public static void main(String[] args) {
A a = new A();
Serializable serializable = new Serializable(){};
a = (A)serializable;
}
}
Run Code Online (Sandbox Code Playgroud)
编译成功但运行时异常
Exception in thread "main" java.lang.ClassCastException: InterfaceCasting$1 cannot be cast to InterfaceCasting$A
Run Code Online (Sandbox Code Playgroud)
为什么汇编成功?编译器必须知道serialiazable不是A?
aio*_*obe 29
正如你所指出的,这将编译:
interface MyInterface {}
class A {}
public class InterfaceCasting {
public static void main(String[] args) {
MyInterface myObject = new MyInterface() {};
A a = (A) myObject;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这不会编译:
interface MyInterface {}
class A {}
public class InterfaceCasting {
public static void main(String[] args) {
A a = (A) new MyInterface() {}; // javac says: "inconvertible types!"
}
}
Run Code Online (Sandbox Code Playgroud)
那么,这里发生了什么?有什么不同?
那么,既然MyInterface是一个简单的界面,就可以很好地通过扩展一个类来实现,在这种情况下,从铸造MyInterface到A会是合法的.
例如,这段代码将在50%的所有执行中成功,并说明编译器需要解决可能不可判定的问题,以便在编译时始终"检测"非法转换.
interface MyInterface {}
class A {}
class B extends A implements MyInterface {}
public class InterfaceCasting {
public static void main(String[] args) {
MyInterface myObject = new MyInterface() {};
if (java.lang.Math.random() > 0.5)
myObject = new B();
A a = (A) myObject;
}
}
Run Code Online (Sandbox Code Playgroud)
Java语言规范声明:
在编译时可以证明某些演员阵容不正确; 这样的强制转换会导致编译时错误.
后来在节目中将编译时参考类型S的值转换为编译时参考类型T的编译时合法性的详细规则 - 当心,它们非常复杂且难以理解.
有趣的规则是:
在你的例子中,非常清楚,演员表是非法的.但请考虑这个微小的变化:
public class InterfaceCasting {
private static class A{}
private static class B extends A implements Serializable{}
public static void main(String[] args) {
A a = new A();
Serializable serializable = new B(){};
a = (A)serializable;
}
}
Run Code Online (Sandbox Code Playgroud)
现在可以在运行时从一个Serializableto A转换,这表明,在这些情况下,最好留给运行时来决定我们是否可以强制转换.
| 归档时间: |
|
| 查看次数: |
26549 次 |
| 最近记录: |