Java 接口转换

Java Interfaces Casting

想象一下,我们有 class C 实现接口 I 和 J,声明为;

I i = new C();

为什么这3个不报错(尤其是最后一个):

1) C c = (C)i;
2) J j = (J)i;
3) i   = (I)null;

提前致谢。

第一个可行,因为 i 是 C 的一个实例(即使引用是类型 I,但对于转换而言引用类型是无关紧要的)。

第二个有效,因为 i 是 C 的一个实例,因此也是 J 的一个实例(因为 C 实现了 J)。引用类型与转换无关。

接口与对象不同"view"。当你调试它时,总是有 "C" 对象。

对于 Null 你可以看这里: No Exception while type casting with a null in java

  1. 之所以有效,是因为 iI 的引用变量,但它包含 的实例]C。如果对象是您要转换到的 class 的实例,则您可以向下转换该对象。

  2. C 实现了 J 并且您始终可以向上转换对象。

  3. 我猜是因为i是一个引用变量,它允许有一个空值,而你给它一个空值。

  1. C c = (C)i;

    因为 i 可以保存类型 C 的实例,所以允许编译器将 I 转换为 C 类型引用没有问题(如果转换在运行时成功我们将确保来自 C 引用的所有方法都将被实例支持,该实例也将是类型 C 或其子类型)。

  2. J j = (J)i;

    因为有可能(就像在我们的例子中)存储在 i 中的实例也将实现 J 接口 compilers 允许我们在两者之间进行转换不相关接口的引用。但是如果存储在 i 中的实例不会实现 J 那么我们将在 runtime.

    得到 ClassCastException
  3. i = (I)null;

    好吧,null 可以分配给 任何 引用,因此允许它分配给 i 或转换它没有问题。

创建对象并使用语句将其分配给 i 后。

    I i = new C();

即使引用它的变量定义为 I,对象仍然是 C。

所以

    C c = (C)i;

只是将同一个对象分配给定义为 C 的新变量。由于对象是 C 类型,所以没有问题。

    j = (J)i;

只是将同一个对象分配给一个定义为 J 的新变量。由于该对象是实现接口 J 的 C 类型,它也是 J 类型,所以没有问题。

    i   = (I)null;

只需将变量 i 设置为 null。