java - 为什么 (int)MethodHandle.invokeExact 缺少 checkcast-instruction?

标签 java casting jvm bytecode methodhandle

我已经为 Java MethodHandle-API 创建了 2 个简单的类:

public class Foo {
    private static int staticField;

    public static Object getStaticField() {
        return staticField;
    }
}

以两种方式调用方法 Foo.getStaticField() 的另一个类 - 直接和使用 MethodHandle-API:

....
public static void methodHandleGetStaticField() throws Throwable {
    MethodHandle methodHandle = lookup.findStatic(Foo.class, "getStaticField", MethodType.methodType(int.class));
    int i = (int)methodHandle.invokeExact();
}

public static void directGetStaticField() {
    int i = (int)Foo.getStaticField();
}
....

我已经反编译类并看到 directGetStaticField 方法包含转换指令 a,但是方法 methodHandleGetStaticField 没有,尽管 java.lang.invoke.MethodHandle.invokeExact () 返回 java.lang.Object

public static void directGetStaticField();
descriptor: ()V
Code:
   0: invokestatic  #70    // Method ru/fj/methodhandle/Foo.getStaticField:()Ljava/lang/Object;
   3: checkcast     #33    // class java/lang/Integer
   6: invokevirtual #74    // Method java/lang/Integer.intValue:()I
   9: istore_0
  10: return

public static void methodHandleGetStaticField() throws java.lang.Throwable;
descriptor: ()V
Code:
   0: getstatic     #15    // Field lookup:Ljava/lang/invoke/MethodHandles$Lookup;
   3: ldc           #29    // class ru/fj/methodhandle/Foo
   5: ldc           #90    // String getStaticField
   7: getstatic     #32    // Field java/lang/Integer.TYPE:Ljava/lang/Class;
  10: invokestatic  #38    // Method java/lang/invoke/MethodType.methodType:(Ljava/lang/Class;)Ljava/lang/invoke/MethodType;
  13: invokevirtual #46    // Method java/lang/invoke/MethodHandles$Lookup.findStatic:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;
  16: astore_0
  17: aload_0
  18: invokevirtual #52    // Method java/lang/invoke/MethodHandle.invokeExact:()I
  21: istore_1
  22: return

谁能帮我解释一下?

最佳答案

你可以注意到 invokeExact确实返回 int从它的描述符 ()I :

  18: invokevirtual #52    // Method java/lang/invoke/MethodHandle.invokeExact:()I

因此,不需要转换。

它返回 int 的原因,不是 Object ,是那种方法invokeExact (以及 invoke )在 MethodHandle 中受到特殊对待,请参阅 invokeExact API

Returns:

the signature-polymorphic result, statically represented using Object

来自 signature polymorphism :

... The unusual part is that the symbolic type descriptor is derived from the actual argument and return types, not from the method declaration.

关于java - 为什么 (int)MethodHandle.invokeExact 缺少 checkcast-instruction?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36743385/

相关文章:

java - 我在 Hadoop 中收到此错误,无法找到可执行文件 null\bin\winutils.exe

java - GWT:在 GET 请求中捕获 URL 参数

java - 使用java从本地商店获取SSL证书到sslContext对象

java - 我的 JVM 内存泄漏在哪里?垃圾收集器工作正常吗?

java - 从不同 JVM 中的 Java 桌面应用程序中执行 Java main 方法

scala - 如何在运行应用程序或测试用例时将JVM选项传递给SBT以使用?

java - 卡片布局 : How to get an event to start only when a particular card is displayed?

Spring Boot data-jpa 和 nativeQuery Postgres cast

c++ - 长的有什么问题?为什么自动减1?

android - 无法转换为 java.lang.Long Android SharedPreferences