本文共 1215 字,大约阅读时间需要 4 分钟。
在JNI中发生的异常和Java完全不一样。我们在写JNI程序的时候,JNI没有像Java一样有try…catch…final这样的异常处理机制,并且在本地代码中调用某个JNI接口时如果发生了异常,后续的本地代码不会立即停止执行,而会继续往下执行后面的代码。
JNIEnv接口提供了一组与异常相关的函数集,在运行过程中可以使用Java类查看这些函数。
public class JavaClass{ // 抛出方法private void throwingMethod() throws NullPointerException{throw new NullPointerException("Null Pointer");}/*** Access methods native method.*/private native void accessMethods();}
调用throwingMethod方法时,accessMethod原生方法需要显示地做异常处理。JNI提供了ExceptionOccurred函数查询虚拟机中是否有挂起的现象。例如,原生代码中的异常处理:
jthrowable ex;……(*env)->CallVoidMethod(env,instance,throwingMethodId);ex = (*env)->ExceptionOccurred(env);if(0 != ex){// 清除引发的异常(*env)->ExceptionClear(env);/*Exception handler*/}
JNI也允许原生代码抛出异常。因为异常是java类,应该先用FindClass函数找到异常类。用ThrowNew函数可以初始化且抛出新的异常,例如:
jclass clazz;……clazz = (*env)->FindClass(env,"java/lang/NullPointerException");if(0 !=clazz){(*env)->ThrowNew(env,clazz,"Exception message");}
当检测到异常时,我们可以调用ExceptionDescribe函数打印这个异常的堆栈信息,然后再调用ExceptionClear函数清除异常堆栈信息的缓冲区(如果不清除,后面调用ThrowNew抛出的异常堆栈信息会覆盖前面的异常信息),最后调用ThrowNew函数手动抛出一个java.lang.Exception异常。
但在JNI中抛出未捕获的异常与Java的异常处理机制不一样,在JNI中并不会立即终止本地方法的执行,而是继续执行后面的代码。这种情况需要我们手动来处理,在执行完异常处理之后直接return返回,不再执行之后的代码。
转载地址:http://kouhj.baihongyu.com/