正在准备 OCA Java SE 7 程序员 I 考试,所以新手问题。我有一个我不明白的示例问题。以下代码可以编译,但在运行时给出 ClassCastException:
interface Roamable {
}
class Phone {
}
public class Tablet extends Phone implements Roamable {
public static void main(String... args) {
Roamable var = (Roamable) new Phone();
}
}
当我改变时Roamable var = (Roamable) new Phone();
into Roamable var = (Roamable) new String();
我立即收到编译错误。
两个问题:
- 为什么上面的代码能够编译?对我来说,电话似乎与可漫游无关?
- 为什么代码编译时会带有
new Phone()
,但它不是用new String()
?
为什么上面的代码能够编译?电话似乎无关
可以漫游给我吗?
是的,因为Roamable
是一个接口,它可能会导致运行时异常,但不会导致编译时异常,因为即使Phone
不执行Roamable
,一个子类Phone
可能,因此编译器除了在运行时之外无法知道它。
java语言规范中已经定义了。在这里查看我的答案 https://stackoverflow.com/questions/19824941/why-does-it-compile-when-casting-to-an-unrelated-interface/19825137#19825137.
为什么代码用new Phone()可以编译,但是编译不通过
用 new String() 吗?
Because class String
被声明为public final class
in java.lang
包裹。如指定jls 8.1.1.2 final class http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.1.2节:声明为的类final
无法扩展,因此它不会有任何子类。所以,编译器已经知道String
无法扩展:因此不可能实现子类的存在界面 Roamable
编辑:(回复您的以下评论)
让我们假设B
是一个子类A
它实现了一个接口T
.
现在声明:
T t = (T)new A();
本质上与以下相同:
A aObj = new A() ;
T t = (T)aObj ; // a run-time exception happen
在得出结论之前,让我们对一个对象做同样的事情B
:
A aObj = new B();
T t = (T)aObj; // no exception happen.
所以,这里超类和子类的真正原因是引用。这aObj
第二个代码示例中的类也是类的实例A
但它也是一个类的实例B
已实施T
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)