JNI攻略之九――操作异常
本篇主要介绍如何在JNI处理java异常,这种异常可以java内部方法的,也可以是JNI中自己创建并且抛出的!同时还复习了JNI中操作java对象的方法!
一、Java类及两个辅助类
//下面是一个包含本地代码的java类!该本地方法调用java方法,同时可能抛出异常。
public class ExceptionAccess{
private static native void doThrowException(int age)throws AgeOutofBoundsException;
//本地方法,调用Student类的setAge方法,抛出异常
public static void main(String[] args){
try {
System.out.println("We are going to set the age ! age = 20");
ExceptionAccess.doThrowException(20); //正常处理
System.out.println();
System.out.println();
System.out.println("We are going to set the age ! age = 101"); //抛出异常
ExceptionAccess.doThrowException(101);
}catch(AgeOutofBoundsException e ){
System.out.println("In Java:/n/t" + e);
}
}
static { //不用说了吧!
System.loadLibrary("ExceptionAccess");
}
}
//以下是一个简单的辅助类!包含一个抛出异常的方法!
class Student{
private int age ;
public void setAge(int age)throws AgeOutofBoundsException{
if(age > 100|| age<0) throw new AgeOutofBoundsException("/nAge is out of bound!Please check your age !/n");
this.age = age ;
}
public int getAge(){
return age ;
}
}
//简单的异常类!继承父异常Exception!
class AgeOutofBoundsException extends Exception{
AgeOutofBoundsException(){
super();
}
AgeOutofBoundsException(String reason){
super(reason);
}
}
二、本地代码实现
//以下是JNI中本地方法的实现
#include <jni.h>
JNIEXPORT void JNICALL Java_ExceptionAccess_doThrowException(JNIEnv *env, jclass cls , jint age ){
jclass stucls ; //Student类的类
jmethodID cmid ,setmid ,getmid ; //Student类的构造器方法、set/get方法
jobject stuobj ; //Student类的一个对象
jthrowable exc; //JNI中的异常――本篇的重点哦!
jint result ; //简单的返回结果
stucls = (*env)->FindClass(env, "Student"); //得到Student类的类
if (stucls == NULL) { return ; }
cmid = (*env)->GetMethodID(env, stucls,"<init>", "()V"); //构造Student类
//在JNI中,构造器其实就是一个名称为"<init>"的方法,返回值为void
if (cmid == NULL) { return ; }
stuobj = (*env)->NewObject(env, stucls, cmid, NULL); //创建该Student类的实例
setmid=(*env)->GetMethodID(env, stucls, "setAge", "(I)V"); //得到Student类的set方法
if (setmid == NULL) { return; }
(*env)->CallVoidMethod(env, stuobj, setmid,age);
//调用Student类的set方法,输入为本地方法中的参数age哦!仔细看清楚了!
exc = (*env)->ExceptionOccurred(env); //从env中得到是否发生异常
if (exc) { //异常发生,则……
jclass newExcCls; //在JNI中创建一个异常对象
(*env)->ExceptionDescribe(env); //得到异常的描述
(*env)->ExceptionClear(env); //清除异常
newExcCls = (*env)->FindClass(env,"AgeOutofBoundsException"); //建立一个对于的异常
if (newExcCls == NULL) {return;}
(*env)->ThrowNew(env, newExcCls, "Thrown from C code!/n Age is out of Bound !/n");
//在JNI中抛出异常!异常到此结束!
}
getmid=(*env)->GetMethodID(env, stucls, "getAge", "()I"); //得getAge方法
if (getmid == NULL) { return; }
result = (*env)->CallIntMethod(env, stuobj, getmid); //调用getAge方法
printf("We are going to set the age ! age = %d/n",result); //在本地方法中输出结果
}