当前位置导航:炫浪网>>网络学院>>编程开发>>JAVA教程>>Java入门

使用 Java Native Interface 的最佳实践3

  未检测异常

  本机能调用的许多 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 的情况,但它并未清除 此调用将设置的异常。因此,本机返回的结果会造成立即抛出一个异常。

共4页 首页 上一页 1 2 3 4 下一页 尾页 跳转到
相关内容
赞助商链接