使用 Java Native Interface 的最佳实践3

欢迎进入Java社区论坛,与200万技术人员互动交流 >>进入

  未检测异常

  本机能调用的许多 JNI 方法都会引起与执行线程相关的异常。当 Java 代码执行时,这些异常会造成执行流程发生变化,这样便会自动调用异常处理代码。当某个本机方法调用某个 JNI 方法时会出现异常,但检测异常并采用适当措施的工作将由本机来完成。一个常见的 JNI 缺陷是调用 JNI 方法而未在调用完成后测试异常。这会造成代码有大量漏洞以及程序崩溃。

  举例来说,考虑调用 GetFieldID() 的代码,如果无法找到所请求的字段,则会出现 NoSuchFieldError。如果本机代码继续运行而未检测异常,并使用它认为应该返回的字段 ID,则会造成程序崩溃。举例来说,如果 Java 类经过修改,导致 charField 字段不再存在,则清单 10 中的代码可能会造成程序崩溃 ― 而不是抛出一个 NoSuchFieldError:

  清单 10. 未能检测异常

  jclass objectClass;   jfieldID fieldID;   jchar result = 0;   objectClass = (*env)->GetObjectClass(env, obj);   fieldID = (*env)->GetFieldID(env, objectClass, ”charField”, ”C”);   result = (*env)->GetCharField(env, obj, fieldID);

  添加异常检测代码要比在事后尝试调试崩溃简单很多。经常,您只需要检测是否出现了某个异常,如果是则立即返回 Java 代码以便抛出异常。然后,使用常规的 Java 异常处理流程处理它或者显示它。举例来说,清单 11 将检测异常:

  清单 11. 检测异常

  jclass objectClass;   jfieldID fieldID;   jchar result = 0;   objectClass = (*env)->GetObjectClass(env, obj);   fieldID = (*env)->GetFieldID(env, objectClass, ”charField”, ”C”);   if((*env)->ExceptionOccurred(env)) {   return;   }   result = (*env)->GetCharField(env, obj, fieldID);

  不检测和清除异常会导致出现意外行为。您可以确定以下代码的问题吗?

fieldID = (*env)->GetFieldID(env, objectClass, ”charField”, ”C”);   if (fieldID == NULL){   fieldID = (*env)->GetFieldID(env, objectClass,”charField”, ”D”);   }   return (*env)->GetIntField(env, obj, fieldID);

  问题在于,尽管代码处理了初始 GetFieldID() 未返回字段 ID 的情况,但它并未清除 此调用将设置的异常。因此,本机返回的结果会造成立即抛出一个异常。

[1][2][3][4]

做对的事情比把事情做对重要。

使用 Java Native Interface 的最佳实践3

相关文章:

你感兴趣的文章:

标签云: