java 的 JNI介绍

—> go to 总目录

内容源于JDK API文档JNI
脑图会列出JNI的功能框架。
JNI技术不做深入,本篇文档描述JNI的使用场景、整体设计、和一个简单用例。方便记忆和理解JNI。

一、概述

提供调用第三方类库,和本地方式的方式。
使用场景

  • java的类库不支持运行平台的特性
  • 调用其他语言的库比如C
  • 要求函数的执行效率要高,封装成本地方法,被java调用

JNI的功能

  • 创建、查看、升级 java对象
  • 调用java方法
  • 捕获异常
  • 加载类和获取类的信息
  • 演示运行时类型检查

二、整体设计

想要调用一个本地方法,通过JNI接口执行,获取一个属于当前线程的JNI指针,这个指针就包含注册好的本地方法
java 的 JNI介绍

    1. 可以类比为JNI interface pointer为类的定义
    1. Pointer指针为实例,每个线程独有,线程之前不能传递。vm的实现者可以在Pointer指针实例的区域开辟一个控件来保存变量信息等,这个就是我们常理解的虚机方法栈,线程级别的。
    1. 具体的蹦迪方法数组就想方法的定义。这样做的好处是,vm不绑定具体的方式,而是只维护一个数组。并且vm可以有多个这样的数组:比如开发阶段用一个,但是check多,耗时多;运行期间用另外一个,check少效率高。

三、编译、加载和链接

System.loadLibrary()

用来加载第三方类库。
java 的 JNI介绍

  • 定义了一个类Pkg.Clg,该类加载pkg_Cls库。比如linux系统就是pkg_Cls.so,win32就是pkg_Cls.dll。
  • 定义了方法native double f(int i, String s)。自动去根据签名在本地方法库中寻找。
  • 注意开发者可以用一个库来存储本地方法,只要被同一个类加载器加载。供应商提供这样的库是应该谨慎选择名称,避免库名冲突。
  • 被加载的方法分为静态方法和非静态方法。使用库名+方法名来标识静态方法,方法名是非静态。
库名 方法名 类别 形式
L JNI_OnLoad 静态 JNI_OnLoad_L
L JNI_OnLoad 非静态 JNI_OnLoad

注意JNI_OnLoad_L和JNI_OnLoad同时存在时会被忽略。

  • 开发者也可以用RegisterNatives()去和一个类链接,这个方法对静态方法十分有用

四、本地方法名称的解析规则

先看这样一个类
java 的 JNI介绍

  • 有两个同名的方法,但不用担心方法冲突。第一个方法在依赖中找,第二个方法去natvie方法中
  • native int g(double d);如何对应到本地方法呢,有转化规则。

java 的 JNI介绍
中的方法对应到C文件中方式是
java 的 JNI介绍

  • java前缀
  • 类名
  • 方法名
  • 参数类型
  • 参数数量

五、引用java对象

在Java和本机代码之间复制原始类型,例如整数,字符等。另一方面,任意的Java对象都是通过引用传递的。VM必须跟踪已传递给本机代码的所有对象,以便垃圾回收器不会释放这些对象。反过来,本机代码必须具有一种通知VM不再需要对象的方法。另外,垃圾收集器必须能够移动由本机代码引用的对象。

  • 数组
  • 方法
  • 字段field

六、异常的处理机制

  • 类型检查(JNI不检查类型)
  • 异常处理机制。