JNI/NDK开发指南(十一)

转载请注明出处:

异常简介

异常,显而意见就是程序在运行期间没有按照正常的程序逻辑执行,在执行过程当中出现了某种错误,导致程序崩溃。在Java中异常分为运行时异常(RuntimeException)和编译时异常,在程序中有可能运行期间发生异常的逻辑我们会用try…catch…来处理,如果没有处理的话,在运行期间发生异常就会导致程序奔溃。而编译时异常是在编译期间就必须处理的。本章主要介绍运行时异常。 示例1:

() {int a = 20 / 0;System.out.println(“—>” + a);}

示例2:

() throws Exception {// …System.out.println(“testException() invoked!”);}(String[] args) {exceptionCallback();try {testException();} catch (Exception e) {e.printStackTrace();}// ….}在示例2中,testException方法声明时显示抛出了一个java.lang.Exception异常,所以在程序调用的地方必须用try…catch处理。

大家都知道,如果示例2中main方法执行到调用exceptionCallback方法时,方法第一行有一个除0的操作,因此该方法会抛出java.lang.ArithmeticException数学异常,而在main方法调用的时候并没有处理这个函数在运行时可能会发生的异常,所以会导致程序立即结束,而后面的代码try{testException();}catch(Exception e) {e.printStackTrace();}都不会被执行。运行示例2程序的你会看到下面的结果:

Exception in thread “main” java.lang.ArithmeticException: / by zeroat (JNIException.java:8)at (JNIException.java:22)

我们改进一下上面这个程序:

(String[] args) {try {exceptionCallback();} catch (Exception e) {e.printStackTrace();}try {testException();} catch (Exception e) {e.printStackTrace();}}

这时我们运行程序,调用exceptionCallback方法时会引发java.lang.ArithmeticException: / by zero异常,由于我们用try…catch块显示处理了异常,所以程序会继续往下执行,调用testException()函数,打印testException() invoked!。运行结果如下所示:

java.lang.ArithmeticException: / by zeroat (JNIException.java:8)at (JNIException.java:24)testException() invoked!Java与JNI处理异常的区别

下面来小结一下: 1、在Java中如果觉得某段逻辑可能会引发异常,用try…catch机制来捕获并处理异常即可 2、如果在Java中发生运行时异常,没有使用try…catch来捕获,会导致程序直接奔溃退出,后续的代码都不会被执行 3、编译时异常,是在方法声明时显示用throw声明了某一个异常,编译器要求在调用的时候必须显示捕获处理 public static void testException() throws Exception {} 上面这几点,写过Java的朋友都知道,而且很简单,但我为什么还要拿出来说呢,其实我想重点说明的是,在JNI中发生的异常和Java完全不一样。我们在写JNI程序的时候,JNI没有像Java一样有try…catch…final这样的异常处理机制,面且在本地代码中调用某个JNI接口时如果发生了异常,后续的本地代码不会立即停止执行,而会继续往下执行后面的代码。

异常处理示例

示例3: 这个例子在main中调用了doit本地方法,在本地方法中会回调exceptionCallback方法,该方法中会引发一个除0的运行时异常java.lang.ArithmeticException,我们通过这个示例来学习在JNI中如何来正确处理这种异常。

package com.study.jnilearn;{();() {int a = 20 / 0;System.out.println(“—>” + a);}() {System.out.println(“In Java: invoke normalCallback.”);}(String[] args) {doit();}static {System.loadLibrary(“JNIException”);}}{#endif/* * Class:com_study_jnilearn_JNIException * Method: doit * Signature: ()V */JNIEXPORT void JNICALL Java_com_study_jnilearn_JNIException_doit (JNIEnv *, jclass);#ifdef __cplusplus}JNIEXPORT void JNICALL Java_com_study_jnilearn_JNIException_doit(JNIEnv *env, jclass cls) {jthrowable exc = NULL;jmethodID mid = (*env)->GetStaticMethodID(env,cls,”exceptionCallback”,”()V”);if (mid != NULL) {(*env)->CallStaticVoidMethod(env,cls,mid);}printf(“In C: Java_com_study_jnilearn_JNIException_doit–>called!!!!”);if ((*env)->ExceptionCheck(env)) { // 检查JNI调用是否有引发异常(*env)->ExceptionDescribe(env);(*env)->ExceptionClear(env);// 清除引发的异常,在Java层不会打印异常的堆栈信息(*env)->ThrowNew(env,(*env)->FindClass(env,”java/lang/Exception”),”JNI抛出的异常!”);//return;}mid = (*env)->GetStaticMethodID(env,cls,”normalCallback”,”()V”);if (mid != NULL) {(*env)->CallStaticVoidMethod(env,cls,mid);}}

程序运行结果如下:

Exception in thread “main” java.lang.ArithmeticException: / by zeroat (JNIException.java:8)at (Native Method)at (JNIException.java:17)Exception in thread “main” java.lang.Exception: JNI抛出的异常!at (Native Method)In Java: invoke normalCallback.at (JNIException.java:17)In C: Java_com_study_jnilearn_JNIException_doit–>called!!!!人,也总是很难发现自己的错误,

JNI/NDK开发指南(十一)

相关文章:

你感兴趣的文章:

标签云: