JNI异常
JNI允许native方法引发任意Java异常。native代码还可以处理未解决的Java异常。未处理的Java异常将传播回VM虚拟机。
异常和错误代码
在两种情况下,程序员需要检查异常:
-
JNI函数调用Java方法并返回Java方法的结果。程序员必须调用
ExceptionOccurred()
以检查在执行Java方法期间可能发生的异常。 -
一些JNI数组访问函数不返回错误代码,但可能会引发
ArrayIndexOutOfBoundsException
或ArrayStoreException
。
在所有其他情况下,非错误返回值可确保不会引发任何异常。
异步异常
在有多个线程的情况下,当前线程以外的其他线程可能会发布异步异常。异步异常不会立即影响当前线程中本机代码的执行,直到:
-
本地代码调用可能引发同步异常的JNI函数之一
-
本地代码用于
ExceptionOccurred()
显式检查同步和异步异常。
请注意,只有那些可能引发同步异常的JNI函数才会检查异步异常。
本地方法ExceptionOccurred()
应在必要的地方插入检查(例如在没有其他异常检查的紧密循环中),以确保当前线程在合理的时间内响应异步异常。
异常处理
处理本地代码中的异常有两种方法:
-
本地方法可以选择立即返回,从而导致引发本机方法调用的Java代码中引发异常。
-
本地代码可以通过调用清除异常方法
ExceptionClear()
清除异常,然后执行自己的异常处理代码。
引发异常后,本地代码必须首先清除异常,然后再进行其他JNI调用。当有异常发生时,可以安全调用的JNI函数是:
ExceptionOccurred() //异常检测,返回一个异常对象,否则返回NULL
ExceptionDescribe() //日志中打印异常
ExceptionClear() //清除异常堆栈信息
ExceptionCheck() //检查是否发生了异常,若有异常返回JNI_TRUE,否则返回JNI_FALSE
ReleaseStringChars()
ReleaseStringUTFChars()
ReleaseStringCritical()
Release<Type>ArrayElements()
ReleasePrimitiveArrayCritical()
DeleteLocalRef()
DeleteGlobalRef()
DeleteWeakGlobalRef()
MonitorExit()
PushLocalFrame()
PopLocalFrame()
与异常相关的方法
Throw(jthrowable obj) //抛出异常,可以在Java层通过try...catch处理
ThrowNew(jclass clazz, const char* message) //在当前线程触发一个异常,并自定义输出异常信息
FatalError(const char* msg) //致命异常,用于输出一个异常信息,并终止当前VM实例(即退出程序)
网友评论