我已经为 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
... 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/