何时使用 CallNonvirtualObjectMethod 及其相关方法?

When to use CallNonvirtualObjectMethod and its related methods?

似乎 CallStaticObjectMethodCallObjectMethodMethod 等等...都是您所需要的。根据文档

CallNonvirtual<type>Method families of routines and the Call<type>Method families of routines are different. Call<type>Method routines invoke the method based on the class of the object, while CallNonvirtual<type>Method routines invoke the method based on the class, designated by the clazz parameter, from which the method ID is obtained. The method ID must be obtained from the real class of the object or from one of its superclasses.

从该描述看来,具体方法 CallNonvirtualObjectMethod 也没有用。

如文档所述,Call<Type>Method 调用对象实际 class 中的方法,而 CallNonvirtual<Type>Method 调用您指定的 class 中的方法。

考虑这个 Java 代码:

public class A {
    public void doSomething() {
        System.out.println("A.doSomething " + this.getClass().getName());
    }
}

public class B extends A {
    public void doSomething() {
        System.out.println("B.doSomething " + this.getClass().getName());
    }
}

public class Test {
    public static native jniTest(B b);
    public static void main(String[] args) {
        B obj = new B();
        jniTest(obj);
    }
}

如果 jniTest 尝试使用 CallVoidMethod 对其参数调用 doSomething,它将打印 "B.doSomething B"。如果它使用 CallNonvirtualVoidMethod,它会打印 "A.doSomething B".

这与 Java 中 super. 调用使用的机制相同(通过 invokespecial 字节码);但是,它不限于调用当前 class 的直接超级 class 中的方法(您不能在 Java 中执行 super.super.something()new B().super.doSomething(),但你可以使用 JNI)。