说我有以下Java代码:

public class Test {
  public static int foo() {
    throw new RuntimeException();
  }
}

它以通常的方式加载 native 库。 native 库注册并缓存JVM或其他任何东西,然后稍后执行此函数:
JNIEnv* sEnv; // initialised somewhere properly
void throwMeARiver() {
  jclass c = sEnv->FindClass("Test");
  jmethodID m = sEnv->GetStaticMethodID(c, "foo", "()I");
  jint i = sEnv->CallStaticIntMethod(c, m);
  printf("Got %d\n", (int)i);
}

显然,sEnv-> CheckException()现在将返回JNI_TRUE,但是 native 函数将输出什么?在Java中,抛出异常会使JVM停止执行其所在的方法,直到找到合适的处理程序为止,因此foo()的返回值是不确定的。那我也是不确定的吗?

我找不到任何规范或其他说明,因此大概是/is/undefined。与大多数JNI函数不同,在这种情况下,CallStaticIntMethod没有“正常”范围。

我现在正在尝试此操作,但是我主要是在询问是否在某处存在强制性行为。

最佳答案

虽然将定义变量i,但其值不确定。在这种情况下,该值很可能为0,但前提是JVM在其实现中初始化了该值。否则,它将等于内存中位于其位置的任何数据。

取决于 native 函数的实现者,可以通过CallXXXMethod()env->CheckException()env->ExceptionOccurred()正确检查env->ExceptionDescribe()之后的异常。最后,调用env->ClearException()以删除该异常。

10-01 08:38