为什么我们可以将Java接口转换为* any *非final类?

时间:2009-08-05 18:52:29

标签: java interface downcast

import java.util.Collection;


public class Test
{
    public static void main(String[] args)
    {
        Collection c = null;
        Test s = null;

        s = (Test) c;
    }
}

在上面的代码示例中,我将一个集合对象转换为Test对象。 (忽略空指针)。 Test无论如何都与 no 有关系,但是这个程序将通过所有编译时检查。

我想知道为什么会这样。我的假设是接口被忽略,因为它们太复杂了。它们没有通用的超类型,每个类都可以实现多个接口,因此类/接口层次结构太复杂而无法有效搜索?

除此之外,我很难过。有谁知道吗?!

3 个答案:

答案 0 :(得分:8)

“非最终”是这里的关键字。你可能有另一个班级

public class Test2 extends Test implements Collection

其实例最终会被分配到s,使得演员完全合法。

答案 1 :(得分:3)

因为Test的子类也可能是Collection的子类型!语言规范的设计有点灵活,允许在运行时验证的强制转换。

答案 2 :(得分:0)

我们可以从不同的角度来查看它:任何非最终类都可以强制转换为ANY接口

import java.util.function.Predicate;

public class Test {
    public static void main(String[] args) {
        Predicate check;

        try {
            /*It's ok to cast to ANY interface because the Base class is not final.
              Java compiler allows it because some class may extend it 
              and implement the predicate interface. 
              So java compiler can check it only at runtime time not compile time.             
            */
            check = (Predicate)(new Base());

            /*
             Java compiler doesn’t allow it because the BaseFinal is final.
             And it means that no one can extend it and implement interface Predicate. 
             So java compiler can check it at compile time.
            */
            //check = (Predicate)(new BaseFinal()); 
        } catch (ClassCastException e) {
            System.out.println("Class Cast Exception");
        }
        check = (Predicate)(Base)(new Child());
    }    
}
final class BaseFinal {};

class Base {}

class Child extends Base implements Predicate {
    public boolean test(Object t) { return true; }
}