Question

import java.util.Collection;


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

        s = (Test) c;
    }
}

In the code sample above, I am casting a collection object to a Test object. (ignoring the null pointer). Test has no relationship to Collection whatsoever, yet this program will pass all compile-time checks.

I'm wondering why this is. My assumption is that interfaces are ignored because they are too complicated. They have no common super-type and each class can implement several interfaces, so the class/interface hierarchy would be too complicated to search efficiently?

Other than that reason I am stumped though. Does anyone know?!

Was it helpful?

Solution

"Non-final" is a keyword here. You may have another class

public class Test2 extends Test implements Collection

whose instance will end up being assigned to s making a cast perfectly legal.

OTHER TIPS

Because a subclass of Test can potentially be a subtype of Collection as well! The language specification is designed to be a bit flexible to permit casts that can be verified at run-time.

We can view it from a different prospective: any non final class can be casted to ANY interface

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; }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top