为什么我们可以将Java接口转换为* any *非final类?
问题描述:
import java.util.Collection;
public class Test
{
public static void main(String[] args)
{
Collection c = null;
Test s = null;
s = (Test) c;
}
}
在上面的代码示例中,我将一个集合对象转换为Test对象。 (忽略空指针)。测试有没有与Collection的关系,但是这个程序将通过所有编译时检查。为什么我们可以将Java接口转换为* any *非final类?
我想知道这是为什么。我的假设是接口被忽略,因为它们太复杂了。它们没有共同的超类型,每个类都可以实现多个接口,所以类/接口层次结构太复杂,无法有效地进行搜索?
除了这个原因,我被困住了。有人知道吗?!
答
“非最终”是这里的一个关键词。您可能有另一个类
public class Test2 extends Test implements Collection
,其实例将最终被分配到s
使铸造完全合法的。
答
因为Test
的子类也可能是Collection
的子类型!语言规范的设计有点灵活,可以允许在运行时进行验证。
啊,我明白了。 如果没有Test的子类实现了Collection,我仍然期望Downcast失败(类似于如果没有找到该类型,只在严格类的层次结构中失败)。那是因为不值得付出努力? – 2009-08-05 19:04:59
编译器无法对类子类进行任何假设。除非该类被标记为'final',否则可以使用它的类文件对其进行子类化。 – notnoop 2009-08-05 19:08:59
换句话说,仅仅因为在编译时没有子类,并不意味着在运行时不能有子类。 – notnoop 2009-08-05 19:09:38