第三章:JNI类型和数据结构

本章讨论了JNI如何将Java类型映射到本机C类型。

本章涵盖以下主题:

基本类型

以下表格描述了Java基本类型及其与机器相关的本机等效类型。

基本类型和本机等效类型
Java类型 本机类型 描述
boolean jboolean 无符号8位
byte jbyte 有符号8位
char jchar 无符号16位
short jshort 有符号16位
int jint 有符号32位
long jlong 有符号64位
float jfloat 32位
double jdouble 64位
void void 不适用

以下定义供参考。

#define JNI_FALSE  0
#define JNI_TRUE   1

jsize整数类型用于描述基数索引和大小:

typedef jint jsize;

引用类型

JNI包括一些引用类型,对应不同类型的Java对象。JNI引用类型组织如下层次结构:

在C中,所有其他JNI引用类型被定义为与jobject相同。例如:

typedef jobject jclass;

在C++中,JNI引入了一组虚拟类来强制子类型关系。例如:

class _jobject {};
class _jclass : public _jobject {};
// ...
typedef _jobject *jobject;
typedef _jclass *jclass;

字段和方法ID

方法和字段ID是常规的C指针类型:

struct _jfieldID;              /* 不透明结构 */
typedef struct _jfieldID *jfieldID;   /* 字段ID */

struct _jmethodID;              /* 不透明结构 */
typedef struct _jmethodID *jmethodID; /* 方法ID */

值类型

jvalue联合类型用作参数数组中的元素类型。它声明如下:

typedef union jvalue {
    jboolean z;
    jbyte    b;
    jchar    c;
    jshort   s;
    jint     i;
    jlong    j;
    jfloat   f;
    jdouble  d;
    jobject  l;
} jvalue;

类型签名

JNI使用Java虚拟机的类型签名表示。以下表格显示了这些类型签名。

Java虚拟机类型签名
类型签名 Java类型
Z boolean
B byte
C char
S short
I int
J long
F float
D double
L 完全限定类 ; 完全限定类
[ 类型 类型[]
( 参数类型 ) 返回类型 方法类型

例如,Java方法:

long f (int n, String s, int[] arr);

具有以下类型签名:

(ILjava/lang/String;[I)J

修改后的UTF-8字符串

JNI使用修改后的UTF-8字符串来表示各种字符串类型。修改后的UTF-8字符串与Java虚拟机使用的相同。修改后的UTF-8字符串被编码,以便仅包含仅包含非空ASCII字符的字符序列可以使用每个字符仅一个字节表示,但所有Unicode字符都可以表示。

范围在\u0001到\u007F之间的所有字符由单个字节表示,如下:

字节中的七位数据给出了所表示字符的值。

空字符('\u0000')和范围在'\u0080''\u07FF'之间的字符由一对字节x和y表示:

字节表示具有值((x & 0x1f) << 6) + (y & 0x3f)的字符。

范围在'\u0800''\uFFFF'之间的字符由3个字节x、y和z表示:

具有值((x & 0xf) << 12) + ((y & 0x3f) << 6) + (z & 0x3f)的字符由这些字节表示。

代码点在U+FFFF以上的字符(所谓的补充字符)通过分别编码其UTF-16表示的两个代理代码单元来表示。每个代理代码单元由三个字节表示。这意味着,补充字符由六个字节uvwxyz表示:

具有值0x10000+((v&0x0f)<<16)+((w&0x3f)<<10)+(y&0x0f)<<6)+(z&0x3f)的字符由这六个字节表示。

多字节字符的字节以大端(高字节在前)顺序存储在class文件中。

此格式与标准UTF-8格式之间存在两个差异。首先,空字符(char)0使用两字节格式而不是一个字节格式进行编码。这意味着修改后的UTF-8字符串永远不会有嵌入的空字符。其次,仅使用标准UTF-8的一个字节、两字节和三字节格式。Java虚拟机不识别标准UTF-8的四字节格式;它使用自己的两次三字节格式代替。

有关标准UTF-8格式的更多信息,请参阅The Unicode Standard, Version 4.03.9 Unicode编码形式部分。