网站首页 > 精选文章 / 正文
本章讨论了JNI如何将Java类型映射到本机C类型。
本章涵盖以下主题:
- 基本类型
- 引用类型
- 字段和方法ID
- 值类型
- 类型签名
- 修改过的UTF-8字符串
原始类型
下表描述了Java原始类型及其机器相关的native等效类型。
原始类型和native等效类型
Java类型 | native类型 | 描述 |
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 引用类型按以下层次结构组织:
- jobject
jclass(java.lang.Class 对象)
jstring(java.lang.String 对象)
jarray(数组)
jobjectArray(对象数组)
jbooleanArray(布尔数组)
jbyteArray(字节数组)
jcharArray(字符数组)
jshortArray(短整型数组)
jintArray(整型数组)
jlongArray(长整型数组)
jfloatArray(浮点型数组)
jdoubleArray(双精度浮点型数组)
jthrowable(java.lang.Throwable 对象)
在 C 中,所有其他 JNI 引用类型都定义为与 jobject 相同。例如:
typedef jobject jclass;
在 C++ 中,JNI 引入了一组虚类来强制子类型关系。例如:
class _jobject {};
class _jclass : public _jobject {};
// ...
typedef _jobject *jobject;
typedef _jclass *jclass;
字段ID 和 方法ID
方法 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 VM 的类型签名表示。下表显示了这些类型签名。
Java VM 类型签名
类型签名 | Java 类型 |
Z | boolean |
B | byte |
C | char |
S | short |
I | int |
J | long |
F | float |
D | double |
L fully-qualified-class ; | fully-qualified-class |
[ type | type[] |
( arg-types ) ret-type | method type |
例如,Java 方法:
long f (int n, String s, int[] arr);
具有以下类型签名:
(ILjava/lang/String;[I)J
修改 UTF-8 字符串
JNI使用修改过的UTF-8字符串来表示各种字符串类型。修改过的UTF-8字符串与Java VM使用的相同。修改过的UTF-8字符串被编码,以便只包含非空ASCII字符的字符序列可以使用每个字符只占用一个字节来表示,但是所有Unicode字符都可以表示。
范围在 \u0001 到 \u007F 内的所有字符用一个字节表示,如下所示:
- 0xxxxxxx
字节中的七个数据位给出所表示字符的值。
空字符('\u0000')和范围在'\u0080'到'\u07FF'内的字符用一对字节 x 和 y 表示:
- x: 110xxxxx
- y: 10yyyyyy
字节表示具有值 ((x & 0x1f) << 6) + (y & 0x3f) 的字符。
范围在'\u0800'到'\uFFFF'内的字符用 3 个字节 x,y 和 z 表示:
- x: 1110xxxx
- y: 10yyyyyy
- z: 10zzzzzz
用字节表示具有值 ((x & 0xf) << 12) + ((y & 0x3f) << 6) + (z & 0x3f) 的字符。
代码点高于 U+FFFF(所谓的补充字符)的字符是通过单独编码其 UTF-16 表示中的两个代理代码单元来表示的。每个代理代码单元由三个字节表示。这意味着,补充字符由六个字节 u,v,w,x,y 和 z 表示:
- u: 11101101
- v: 1010vvvv
- w: 10wwwwww
- x: 11101101
- y: 1011yyyy
- z: 10zzzzzz
用六个字节表示具有值0x10000+((v&0x0f)<<16)+((w&0x3f)<<10)+(y&0x0f)<<6)+(z&0x3f)的字符。
多字节字符的字节以大端(高字节优先)的顺序存储在类文件中。
此格式与标准UTF-8格式之间有两个区别。首先,使用两个字节格式而不是一个字节格式来编码空字符(char)0。这意味着修改过的UTF-8字符串从不包含嵌入的null。其次,仅使用标准UTF-8的一字节、两字节和三字节格式。Java VM不识别标准UTF-8的四字节格式;它使用其自己的两倍三字节格式。有关标准UTF-8格式的更多信息,请参阅Unicode标准第4.0版的第3.9节“Unicode编码表单”。
本文原文地址:
https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html
Tags:native2ascii
- 上一篇:Blob-对象介绍
- 下一篇:Linux文件类基础命令(包含原理讲解)
猜你喜欢
- 2025-01-18 大数据Hadoop之——数据仓库Hive
- 2025-01-18 Bun v0.6.9 发布!
- 2025-01-18 「网络工程师」无线网络AC+AP配置
- 2025-01-18 教你解锁Markdown高级用法,提升写作效率,建议收藏
- 2025-01-18 java做支付接口测试
- 2025-01-18 锐捷-无线AC统一管理AP配置(命令行)一
- 2025-01-18 阿里开源!又一款序列化框架来了,性能炸裂!
- 2025-01-18 Linux文件类基础命令(包含原理讲解)
- 2025-01-18 Blob-对象介绍
- 2025-01-18 多学习才能多赚钱之:c语法与java语法区别