Java 是否需要检查强制转换?
字节码的第一个版本对我来说有点古怪,尤其是Java 是否需要检查强制转换?,java,java-8,Java,Java 8,字节码的第一个版本对我来说有点古怪,尤其是CHECKCAST p/X 我不明白。我知道在运行时有一种泛型类型的擦除(因此,实际上f.apply(1)返回Object,而不是X,而supp返回X。因此,这个复选框看起来像java(解释器)会尝试确保f.apply(1)返回X 但是,为什么必须这样做呢?看起来java不信任javac。基本上,java中没有真正的泛型-所有的操作都是基于编译时的类型检查。必须执行CHECKCAST,因为类型擦除的结果是在运行时没有关于函数返回类型的信息 例如,没有任何
CHECKCAST p/X
我不明白。我知道在运行时有一种泛型类型的擦除(因此,实际上f.apply(1)
返回Object
,而不是X
,而supp
返回X
。因此,这个复选框看起来像java
(解释器)会尝试确保f.apply(1)
返回X
但是,为什么必须这样做呢?看起来
java
不信任javac
。基本上,java中没有真正的泛型-所有的操作都是基于编译时的类型检查。必须执行CHECKCAST
,因为类型擦除的结果是在运行时没有关于函数返回类型的信息
例如,没有任何东西可以阻止您将原始函数
传递给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
此代码编译(带有未选中的分配警告),但在运行时抛出一个
ClassCastException
。:第二点:如果需要,插入类型强制转换以保持类型安全。supp
必须返回一个X
@ElliottFrisch,但请注意,f
是supp
的一个参数。因此它必须返回X
,因为ret方法签名中的urn类型public X supp
-右边的所有内容都不重要(对于演员).我不明白你现在是什么意思。什么部分让人困惑?如果你的方法是void
,那么在方法的返回值上就不会有CHECKCAST
。请注意,由于类型擦除,前一行的函数.apply
正在使用对象/对象。
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
X x = new X();
Function f = o -> new Y();
x.supp(f);