• Java Native Interface 六JNI中的异常


    本文是《The Java Native Interface Programmer’s Guide and Specification》读书笔记


    在这里只讨论调用JNI方法可能会出现的异常,

    在本地方法里捕捉并抛出异常

    下面的例子说明怎样声明一个可能抛出异常的本地方法:

    class CatchThrow {
       //声明一个本地方法,并可能会抛出不合法参数异常
        private native void doit()
            throws IllegalArgumentException;
        private void callback() throws NullPointerException {
            throw new NullPointerException("CatchThrow.callback");
        }
    

    本地方法的实现为:

    JNIEXPORT void JNICALL
    Java_CatchThrow_doit(JNIEnv *env, jobject obj)
    {
        jthrowable exc;
        jclass cls = (*env)->GetObjectClass(env, obj);
        jmethodID mid =
            (*env)->GetMethodID(env, cls, "callback", "()V");
        if (mid == NULL) {
            return;
        }
        (*env)->CallVoidMethod(env, obj, mid);
        //判断是否发生了异常
        exc = (*env)->ExceptionOccurred(env);
        if (exc) {
            /* 我们对发生的异常只是简单的打印出一条消息指明发生了什么异常,在清除这个异常的同时抛出一个新的异常 */
            jclass newExcCls;
            //对发生的异常进行描述
            (*env)->ExceptionDescribe(env);
            //清除掉发生的异常
            (*env)->ExceptionClear(env);
            newExcCls = (*env)->FindClass(env,
                          "java/lang/IllegalArgumentException");
            if (newExcCls == NULL) {
                /* Unable to find the exception class, give up. */
                return;
            }
        //抛出一个新的异常
    (*env)->ThrowNew(env, newExcCls, "thrown from C code");
        }
    }
    

    当我们执行下面的main方法后:

        public static void main(String args[]) {
            CatchThrow c = new CatchThrow();
            try {
                c.doit();
            } catch (Exception e) {
                System.out.println("In Java:
    	" + e);
            }
        }
        static {
            System.loadLibrary("CatchThrow");
        }
    }
    

    就会得到下面的输出:

    java.lang.NullPointerException:
            at CatchThrow.callback(CatchThrow.java)
            at CatchThrow.doit(Native Method)
            at CatchThrow.main(CatchThrow.java)
    In Java:
            java.lang.IllegalArgumentException: thrown from C code
    

    需要注意的是通过JNI方法ThrowNew抛出异常,并不会立刻打断本地方法的执行,因此需要编程人员明确地指定在发生异常后,控制权应该怎样转换。这是与Java里的异常处理所不同的地方,在Java里,一旦发生异常,JVM就自动将控制权交给最近的与所发生所匹配的try-catch块进行异常的处理。

    我们可以通过两种方法来检查在JNI方法里是否发生了异常:

    1. 使用特殊的返回值来表示发生了异常(如NULL);
    2. 当方法1没有作用时(所返回值可能对于所调用方法是合法的),需要在本地代码里通过抛出异常来进行异常的的处理,在JNI中可以用ExceptionOccurredExceptionCheck方法来检查是否发生了异常。

    本地方法里对异常进行处理

    在本地方法里对异常处理,通常有两种方法:

    1. 在发生异常时,直接返回,让方法的调用者进行处理;
    2. 用JNI方法ExceptionClear将异常清除掉,并执行自己的异常处理代码;

    在调用大部分JNI方法前,对异常进行检查,处理,清除都是非常重要的。

  • 相关阅读:
    C语言静态库与动态库(Windows下测试)
    gcc编译过程
    IFC2x3标准阅读
    ES6学习笔记(二十二)ArrayBuffer
    tensorflow学习笔记(一)安装
    ES6学习笔记(二十一)编程风格
    ES6学习笔记(二十)Module 的加载实现
    ES6学习笔记(十九)Module 的语法-export和import
    ES6学习笔记(十七)Class 的基本语法
    4、配置文件Json(未解决开通云开发)
  • 原文地址:https://www.cnblogs.com/WoodJim/p/4800334.html
Copyright © 2020-2023  润新知