ClassCastException 与“无法转换"编译错误 [英] ClassCastException vs. "cannot cast" compilation error
问题描述
正在为我的 OCA Java SE 7 Programmer I 考试而学习,所以是新手问题.我有一个我不明白的示例问题.以下代码可以编译,但在运行时给出 ClassCastException:
Studying for my OCA Java SE 7 Programmer I exam, so newbie question. I have an example question I do not understand. The following code compiles, but gives a ClassCastException at runtime:
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();
更改为 Roamable var = (Roamable) new String();
时,我立即收到编译错误.
When I change Roamable var = (Roamable) new Phone();
into Roamable var = (Roamable) new String();
I get a compilation error right away.
两个问题:
- 为什么上面的代码完全可以编译?电话似乎与 Roamable 无关?
- 为什么代码用
new Phone()
编译,而不用new String()
编译?
- Why does the code above compile at all? Phone seems unrelated to Roamable to me?
- Why does the code compile with
new Phone()
, but doesn't it compile withnew String()
?
推荐答案
为什么上面的代码完全可以编译?电话似乎与可以漫游给我吗?
Why does the code above compile at all? Phone seems unrelated to Roamable to me?
是的,因为 Roamable
是一个接口,它可能会导致运行时异常但不会导致编译时异常,因为即使 Phone
没有实现 Roamable
,Phone
的子类可能,因此编译器只能在运行时知道它.
yes because Roamable
is an interface it might cause a Run-time exception but not compile time exception, because even if Phone
doesn't implement Roamable
, a subclass of Phone
might, hence the compiler has no way to know it but at the Run time.
它已经在java语言规范中定义了.在这里查看我的回答.
It is already defined in java language specification. Check out my answer here.
为什么代码用new Phone()编译了,但是不编译使用 new String()?
Why does the code compile with new Phone(), but doesn't it compile with new String()?
因为class String
在java.lang
包中被声明为public final class
.如中所述jls 8.1.1.2 final class
部分:声明为 final
的类不能扩展,因此它不会有任何子类.所以,编译器已经知道String
不能被扩展:因此没有子类的存在可以实现interface Roamable
Because class String
is declared as public final class
in java.lang
package. As specified in jls 8.1.1.2 final class
section: a class declared as final
can't be extended and hence it won't have any subclass. So, the compiler already knows that String
can't be extended: hence no subclass's existence is possible to implement interface Roamable
(回复您的以下评论)
让我们假设 B
是 A
的子类,它实现了一个接口 T
.
Let us assume that B
is a subclass of A
which implements an interface T
.
现在声明:
T t = (T)new A();
本质上是一样的:
A aObj = new A() ;
T t = (T)aObj ; // a run-time exception happen
在得出结论之前,让我们对 B
的对象做同样的事情:
before running into conclusion, let us do the same thing with an object of B
:
A aObj = new B();
T t = (T)aObj; // no exception happen.
所以,这里有超类和子类的真正原因是参考.第二个代码示例中的 aObj
类也是 A
类的一个实例,但它也是 B
类的一个实例,它实现了 T
.
so, the real reason with super class and sub class here is the reference. The aObj
class in this second code example is also an instance of class A
but it is also an instance of class B
which has implemented T
.
这篇关于ClassCastException 与“无法转换"编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!