java - CHECKCAST 是否必要?

标签 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 而不是 Xsupp 返回 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/

相关文章:

Java + 如何在字符串值中查找回车符

Java - 在静态函数中构造泛型类的多个对象

特定模式的 Java 正则表达式

java - 使用流从 Json 创建嵌套映射

java-8 - java8中列表的迭代列表

java-8 - Java流操作

Javahelp 查看器(或替代品)

java - 将 JSON 数组解析为列表

java - 除非调用相应的方法,否则 Lambda 主体不会执行

java - 如果使用 Files.find(),则出现 AccessDeniedException