CHECKCAST是否必要?

时间:2018-02-17 15:30:15

标签: java java-8

package p;

public class X {
    private int x;

    public X supp(Function<Integer, X> f){
        return f.apply( 1);
    }
}

supp的字节码:

  public supp(Ljava/util/function/Function;)Lp/X;
   L0
    LINENUMBER 24 L0
    ALOAD 1
    ICONST_1
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
    INVOKEINTERFACE java/util/function/Function.apply (Ljava/lang/Object;)Ljava/lang/Object;
    CHECKCAST p/X
    ARETURN
   L1
    LOCALVARIABLE this Lp/X; L0 L1 0
    LOCALVARIABLE f Ljava/util/function/Function; L0 L1 1

字节码的第一个版本对我来说有点古怪,特别是CHECKCAST p/X

我不明白。我知道运行时存在泛型类型擦除(实际上,f.apply(1)返回Object而不是X,而supp返回X。所以这个检查看似java(解释器)的转换会尝试确保f.apply(1)实际上返回X

但是,为什么有必要呢?看起来java不信任javac。基本上,在编译时基于类型检查的Java中没有真正的泛型。

1 个答案:

答案 0 :(得分:3)

CHECKCAST是必需的,因为由于类型擦除,在运行时没有关于函数返回类型的信息。

例如,没有什么可以阻止您将原始Function传递给supp方法:

X x = new X();
Function f = o -> new Y();
x.supp(f);

此代码编译(带有未经检查的赋值警告),但在运行时抛出ClassCastException