美文网首页
JNI--异常处理

JNI--异常处理

作者: aruba | 来源:发表于2020-04-09 14:21 被阅读0次

JAVA中可以使用try catch捕获异常,那么JNI中如果发生了异常会是什么现象呢?

我们在JAVA中定义native方法,并调用
package com.aruba.jniapplication;

/**
 * JNI 引用
 */
public class JniDemo6 {

    static {
        System.load("C:\\Users\\tyqhc\\source\\repos\\JniApplication\\x64\\Debug\\JniApplication.dll");
    }

    public native void getException();

    public static void main(String[] args) {
        JniDemo6 jniDemo6 = new JniDemo6();
        try {
            jniDemo6.getException();
        } catch (Exception e) {
            
        }
    }

}

编写C++代码,故意报一个异常
//获取异常
JNIEXPORT void JNICALL Java_com_aruba_jniapplication_JniDemo5_getException
(JNIEnv* env, jobject jobj) {
    jclass jclz = env->GetObjectClass(jobj);
    jfieldID fid = env->GetFieldID(jclz,"key","Ljava/lang/String;");

    jstring jstr = (jstring)env->GetObjectField(jobj,fid);

    printf("c++ have exception \n");
}
很明显JniDemo6 中并没有key这个成员变量,编译后运行,看java是否能够捕获异常:
结果是:Java的try catch并捕获不到native方法的异常,还是报错了!但是C++代码还能往下执行,打印输出了信息!
JNI中异常处理有用自己的一套规则,需要JNI开发者在有可能产生异常的位置,调用env的ExceptionCheck方法,检查一下是否有异常
//获取异常
JNIEXPORT void JNICALL Java_com_aruba_jniapplication_JniDemo6_getException
(JNIEnv* env, jobject jobj) {
    jclass jclz = env->GetObjectClass(jobj);
    jfieldID fid = env->GetFieldID(jclz,"key","Ljava/lang/String;");

    jstring jstr = (jstring)env->GetObjectField(jobj,fid);

    //检查是否有异常
    jboolean has_exception =  env->ExceptionCheck();
    if (has_exception) {
        //清空异常
        env->ExceptionClear();
    }

    printf("c++ have exception \n");
}
在执行Java代码
    public static void main(String[] args) {
        JniDemo6 jniDemo6 = new JniDemo6();
        try {
            jniDemo6.getException();
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
Java层已经不会报错了,但是也没有捕获异常,因为在native层已经将这个异常清掉了,我们需要手动创建一个异常告诉Java层,修改c++代码:
//获取异常
JNIEXPORT void JNICALL Java_com_aruba_jniapplication_JniDemo6_getException
(JNIEnv* env, jobject jobj) {
    jclass jclz = env->GetObjectClass(jobj);
    jfieldID fid = env->GetFieldID(jclz,"key","Ljava/lang/String;");

    jstring jstr = (jstring)env->GetObjectField(jobj,fid);

    //检查是否有异常
    jboolean has_exception =  env->ExceptionCheck();
    if (has_exception) {
        //清空异常
        env->ExceptionClear();
        jclass newExc = env->FindClass("java/lang/Exception");
        if(newExc != NULL)  env->ThrowNew(newExc,"c++ have exception to Java");
    }

    printf("c++ have exception \n");
}
在执行Java代码:
JNI的异常处理就到此结束了,总之有点坑爹,需要我们自己创建Java层的异常,Java才能捕获异常

相关文章

  • JNI--异常处理

    JAVA中可以使用try catch捕获异常,那么JNI中如果发生了异常会是什么现象呢? 我们在JAVA中定义na...

  • 同步或异步异常处理

    同步或异步异常处理 同步读取异常处理 异步读取文件异常处理

  • Java 异常

    异常处理机制 异常处理模型:终止模型:当异常发生时,就进入异常处理程序,处理结束并不返回异常发生位置继续执行;恢复...

  • 第十二章:异常处理

    异常处理语法格式: try: ...处理语句 except 异常类型: ...异常处理语句 pytho...

  • Spring MVC 全局统一异常处理(注解方式)

    全局异常处理 对异常处理类增加@ControllerAdvice 增加异常处理方法,使用@ExceptionHan...

  • 异常处理设计文档

    一、异常处理流程说明 在ESB处理过程中,若发生异常,将进入异常流程的处理。一个异常处理流程大致如下: ESB处理...

  • Java异常处理机制

    什么是异常处理机制: 异常处理机制: 让程序发生异常时,按照代码预先设定的异常处理逻辑,针对性地处理异常,让程序尽...

  • ASP .NET Core Web API_05_异常处理

    默认异常处理 自定义异常处理

  • springboot 异常捕获和处理

    springboot 异常捕获和处理 异常捕获处理

  • NDK开发---C++学习(七):异常

    前言 C++的异常处理机制能够将异常检测与异常处理分离开来,当异常发生时,它能自动调用异常处理程序进行错误处理。把...

网友评论

      本文标题:JNI--异常处理

      本文链接:https://www.haomeiwen.com/subject/rmpqmhtx.html