想一想上节中,我们提到了D代表double的方法.
想不起来不要紧,再贴一次
jfieldID id_salary = (*env)->GetFieldID(env, class_Employee, "salary", "D");
很困惑吧,D是个什么东西?
为了访问实例域和调用Java编程语言中定义的方法,你必须学习“编入”数据类型的名称和方法签名的规则(方法签名描述了参数和该方法返回值的类型)。下面是编码方案(类型签名):
在jni.h中有说明
typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue;
上面是所有类型的对应签名。
所以,你要告诉java你想要的类型,你就需要使用这种方式。
我们看到最后一行,L对应的是object,那如果我们要表示String呢,要如下表示:
Ljava/lang/String
数组的表示如下:
[Ljava/lang/String
float[][]的表示如下:
[[F
要建立一个方法的完整签名,需要把括号内的参数类型都列出来,然后列出返回值的类型。
例如,一个接受两个整形参数并返回一个整数的方法编码为:
(II)I
前面使用过的print方法的签名是:
(Ljava/lang/String;)V
注意,在L表达式结尾处的分号是类型表达式的终止符,不是参数之间的分隔符,例如:
Employee(java.lang.String, double, java.util.Date)
具有签名如下:
(Ljava/lang/String;DLjava/util/Date;)V
看到了把,D和Ljava/util/Date;之间没有;。注意,即使对Java的构造器没有指定返回类型,也需要将V添加到虚拟机签名中。(等等,头有点疼。这类型签名规则。我表示无力吐槽了。您老再诡异点可以么?)
可以使用带有选项-s的javap命令来总类型文件产生方法签名,例如,运行javap -s -private Employee就可以得到所有变量和方法的签名了。
其实,设计者可以设计出简单的签名描述方法如void(int,java.lang.String)。但是,上面我们的方法,让你可以更接近虚拟机的编程奥秘。