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 中没有真正的泛型——一切都基于编译时的类型检查。
最佳答案
CHECKCAST
是必需的,因为作为类型删除的结果,在运行时没有关于函数返回类型的信息。
例如,没有什么可以阻止您将原始 Function
传递给 supp
方法:
X x = new X();
Function f = o -> new Y();
x.supp(f);
此代码编译(带有未经检查的分配警告),但在运行时抛出 ClassCastException
。
关于java - CHECKCAST 是否必要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48842887/