JNI 定义了一系列的C/C++类型,来对应Java的基本类型和引用类型。C/C++要想使用这些类型,需要在头文件引用jni.h。
基本类型
下表介绍了Java的基本类型对应的JNI类型。就像Java语言那样,所有JNI的基本类型也都明确定义了其所占的字节数。
Java Language Type | Native Type | Description |
---|---|---|
boolean | jboolean | unsigned 8bits |
byte | jbyte | signed 8 bits |
char | jchar | unsigned 16 bits |
short | jshort | signed 16 bits |
int | jint | signed 32 bits |
long | jlong | signed 64 bits |
float | jfloat | 32 bits |
double | jdouble | 64bits |
JNI中关于基本类型的源码:
/*
* Primitive types that match up with Java equivalents.
*/
#ifdef HAVE_INTTYPES_H
# include <inttypes.h> /* C99 */
typedef uint8_t jboolean; /* unsigned 8 bits */
typedef int8_t jbyte; /* signed 8 bits */
typedef uint16_t jchar; /* unsigned 16 bits */
typedef int16_t jshort; /* signed 16 bits */
typedef int32_t jint; /* signed 32 bits */
typedef int64_t jlong; /* signed 64 bits */
typedef float jfloat; /* 32-bit IEEE 754 */
typedef double jdouble; /* 64-bit IEEE 754 */
#else
typedef unsigned char jboolean; /* unsigned 8 bits */
typedef signed char jbyte; /* signed 8 bits */
typedef unsigned short jchar; /* unsigned 16 bits */
typedef short jshort; /* signed 16 bits */
typedef int jint; /* signed 32 bits */
typedef long long jlong; /* signed 64 bits */
typedef float jfloat; /* 32-bit IEEE 754 */
typedef double jdouble; /* 64-bit IEEE 754 */
#endif
/* "cardinal indices and sizes" */
typedef jint jsize;
引用类型
在C中,所有其他的JNI引用类型都被定义成jobject。比如:
typedef jobject jclass;
在C++中,JNI通过使用一系列的子类继承关系来表示不同的引用类型。
JNI引用类型源码:
#ifdef __cplusplus
/*
* Reference types, in C++
*/
class _jobject {};
class _jclass : public _jobject {};
class _jstring : public _jobject {};
class _jarray : public _jobject {};
class _jobjectArray : public _jarray {};
class _jbooleanArray : public _jarray {};
class _jbyteArray : public _jarray {};
class _jcharArray : public _jarray {};
class _jshortArray : public _jarray {};
class _jintArray : public _jarray {};
class _jlongArray : public _jarray {};
class _jfloatArray : public _jarray {};
class _jdoubleArray : public _jarray {};
class _jthrowable : public _jobject {};
typedef _jobject* jobject;
typedef _jclass* jclass;
typedef _jstring* jstring;
typedef _jarray* jarray;
typedef _jobjectArray* jobjectArray;
typedef _jbooleanArray* jbooleanArray;
typedef _jbyteArray* jbyteArray;
typedef _jcharArray* jcharArray;
typedef _jshortArray* jshortArray;
typedef _jintArray* jintArray;
typedef _jlongArray* jlongArray;
typedef _jfloatArray* jfloatArray;
typedef _jdoubleArray* jdoubleArray;
typedef _jthrowable* jthrowable;
typedef _jobject* jweak;
#else /* not __cplusplus */
/*
* Reference types, in C.
*/
typedef void* jobject;
typedef jobject jclass;
typedef jobject jstring;
typedef jobject jarray;
typedef jarray jobjectArray;
typedef jarray jbooleanArray;
typedef jarray jbyteArray;
typedef jarray jcharArray;
typedef jarray jshortArray;
typedef jarray jintArray;
typedef jarray jlongArray;
typedef jarray jfloatArray;
typedef jarray jdoubleArray;
typedef jobject jthrowable;
typedef jobject jweak;
#endif /* not __cplusplus */
jvalue类型
jvalue是引用类型和基本类型的联合体。
jvalue的定义:
typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue;
字段和方法IDs
字段和方法的IDs被定义为c指针类型
struct _jfieldID; /* opaque structure */
typedef struct _jfieldID* jfieldID; /* field IDs */
struct _jmethodID; /* opaque structure */
typedef struct _jmethodID* jmethodID; /* method IDs */
类描述符
类描述符用来表示一个类或者接口的名字。把类或者接口在java中所定义的完整名称中的”.”替换成”/”就是类描述符。
比如java.lang.String的类描述符为:
“java/lang/string”
数组类的描述符:在”[“后面跟着数组元素的类型的字段描述符。
比如:
“int[]”的类描述符为:”[I”
“double[][][]”的类描述符为:”[[[D”
字段描述符
8个基本类型的字段描述符如下:
Java Language Type | Field Descriptor |
---|---|
boolean | Z |
byte | B |
char | C |
short | S |
int | I |
long | J |
float | F |
double | D |
引用类型的字段描述符的第一个字符是”L”,接着写类描述符,最后以”;”结尾。
数组类型的字段描述符的定义规则和数组类描述符一致。
下面的例子是引用类型的字段描述符和他们相对应的java类型:
Java Language Type | Field Descriptor |
---|---|
String | “Ljava/lang/String;” |
int[] | “[I” |
Object[] | “[Ljava/lang/Object;” |
方法描述符
- 方法描述符首先在”()”中写所有的参数类型的字段描述符,然后在”()”后面接着写返回类型的字段描述符。
- 并且在参数类型的字段描述符之间不能有空格或者其他分隔符。
- “V”用来表示没有返回类型。
- 构造函数使用”V”做为返回类型,并且使用”< init>”做为函数名。
下面的例子是jni的方法描述符以及其对应的方法和构造函数。
Java Language Type | Method Descriptor |
---|---|
String f(); | “()Ljava/lang/String;” |
long f(int i, Class c); | “(ILjava/lang/Class;)J” |
String(byte[] bytes); | “([B)V” |