java源码解析——RegisterNatives()方法
在学习JDK的反射机制与底层源码的时候,常常会看到一个私有本地方法private static native void registerNatives();
。
那么它究竟是做什么的呢?
知识储备
首先你需要了解如下基础知识:
- 了解C语言或C++语言的基础知识
- 具备JavaSE的基础
- 了解Java的JNI技术
registerNatives()
介绍
这个方法主要的目的就是为了注册本地的方法,具体怎么注册呢。就是将Java中的本地方法与C或C++语言编写的函数进行映射关联。
在做JNI开发的时候,你可能会使用javah
生成头文件。在C代码中include
生成的头文件。利用这种方式实现的库,就不需要去做函数映射。
Java JNI实现:
package com.aijiao.test;
public class JNIDemo {
//定义一个方法,该方法在C中实现
public native void testHello();
public static void main(String[] args){
//加载C文件
System.loadLibrary("TestJNI");
JNIDemo jniDemo = new JNIDemo();
jniDemo.testHello();
}
}
利用javah
生成的头文件:
#include "com_aijiao_test_JNIDemo.h"
#include <iostream>
#include <stdio.h>
JNIEXPORT void JNICALL Java_com_aijiao_test_JNIDemo_testHello
(JNIEnv *, jobject) {
printf("this is C++ print");
}
从上面的代码中可以看到,它们之间默认就有一种一一对应的映射协议,这样的JNI就不需要去做注册。只需要在开始阶段加载这个Library文件(windows一般为dll,Linux一般为so)即可。
若您在开发的过程中没有按照这种映射协议去生成Library文件,那么就需要使用registerNatives()
来进行注册了。
例如,java.lang.Object.registerNatives对应的C函数被命名Java_java_lang_Object_registerNatives。通过使用registerNatives(或者说,JNI函数RegisterNatives),你可以任意指定你的C函数。
这是关联的C代码(来自OpenJDK 6):
static JNINativeMethod methods[] = {
{"hashCode", "()I", (void *)&JVM_IHashCode},
{"wait", "(J)V", (void *)&JVM_MonitorWait},
{"notify", "()V", (void *)&JVM_MonitorNotify},
{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};
JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}
现在你应该能明白,registerNatives()
方法的主要目的就是为了建立JVNM与C语言库交互的映射关系,使JVM可以得到操作系统的支持。这也是Java实现跨平台的主要原理。
java源码解析——RegisterNatives()方法
https://blog.cikaros.top/doc/7a5e4e12.html