简体   繁体   中英

Java Generics Interface casting

I stumbled across a Java casting situation involving Generics and Interfaces that I do not understand.

Please consider the following code where I create a List<Interface1> . And then get() an element and cast it to Interface2 without compiler error although these two interfaces are completely unrelated.

import java.util.*;

public class Main {
  public static void main(String ... args) {
    List<Interface1> list = new ArrayList<>();
    list.add(new Interface1() {});

    Interface1 ok = list.get(0);
    Interface2 why = (Interface2)list.get(0);
  }
}

interface Interface1 {
}

interface Interface2 {
}

Can anyone explain why there is not compiler error for the cast at the second get(0) ?

Two side notes: Executing the class throws a ClassCastException (as expected). And using two classes instead of interfaces does actually generate compile errors.

This behaviour is unrelated to generics: you can cast any interface to any other without compile errors.

You cannot do this with classes because Java can check at compile time whether one class can be casted to another.

With interfaces however the cast might succeed or fail, depending on the class that is actually implementing the interface. This can be discovered only at runtime though.

If you have a type which implements Interface1 it may as well implement Interface2 . Hence the compiler will not blame you, because at runtime the cast may succeed.

This is because JAVA supports multiple interface implementations. As we can have any number of classes of any types(any parent class) that can implement an interface, JVM design is such that untill runtime one cannot identify which type is being passed in place that interface.So there can be any interface placed in the ArryList

The compiler does not know that this won't work: You could have a instance of type Interface2 that is also of type Interface1 (for ex: class ImplementingClass implements Interface1,Interface2). Then the cast would be fine.

"using two classes instead of interfaces does actually generate compile errors."

In this situations compiler knows that it won't work, and due to this you are getting compilation error in this case.

There is possibility, that sub class of Interface1 can be a sub class of Interface2 also. So, it doesn't give the compilation error.

It not generic problem. JVM nothing "known" about compatibilities between Interface1 and Interface2 . So you get ClassCastException .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM