缩小参考转换

Narrowing Reference Conversion

取自http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html

5.1.6. Narrowing Reference Conversion Six kinds of conversions are called the narrowing reference conversions: From any reference type S to any reference type T, provided that S is a proper supertype of T ...

public class S {}

public class T extends S {}

如下抛出一个java.lang.ClassCastException

S s = new S();
T t = (T)s;

'conversion' 是否仅指以下内容 编译 不会抛出 运行 时间异常。

S s = null;
T t = (T)s;

执行此转换的原因是什么?

在您引用的 document 中进一步说明

Such conversions require a test at run time to find out whether the actual reference value is a legitimate value of the new type. If not, then a ClassCastException is thrown.

转换也适用于您的第一个示例。类型 S 的值不是 类型 T 的合法值。 The value null is a legitimate value of type T.

The null reference can always be assigned or cast to any reference type (§5.2, §5.3, §5.5).

编译器相信您知道自己在做什么。 JVM 没有。

缩小引用转换通常称为向下转换。它通常用于您有一些超类型的引用但想根据它们的实际类型对它们做一些更具体的事情的情况。

Object superTypeReference = // something;
if (superTypeReference instanceof List) {
    List<?> subtypeReference = (List<?>) superTypeReference;
    subtypeReference.clear();
}

尽管在 Sotirios Delimanolis 的示例中是隐含的 (// something),但我想补充一点并明确说明,如果您有:

public class S {}
public class T extends S {}

然后 JLS 中的缩小转换不仅指的是您使用 null 的示例,而是指:

S s = new T();
T t = (T) s; // compiles and won't give a ClassCastException

正如你所说

S s = new S();
T t = (T) s;

将编译但会抛出一个 ClassCastException