java本地方法在哪里
java本地方法在哪里
在代码里,标记了native关键字的方法就是本地方法,由于没有方法体,叫做本地方法接口。本地方法接口调非java代码,可能是c、c++或者其它。这里就有一个疑问,它是怎么知道调用哪个c代码的,是怎么联系的呢?
以Object类的hashCode方法为例
public class Object {
...
public native int hashCode();
...
}
Object类的hashCode方法是本地方法。
有两个文件 .h文件 和 .c文件
.h文件
有本地方法的类可生成一个对应的.h文件。
进入Object.class所在的文件夹:jdk1.8.0_231\jre\lib\rt.jar!\java\lang\Object.class
(需要到jdk的安装目录,解压rt.jar)
执行命令:javah -jni java.lang.Object
,就可以生成对应的.h文件,文件名为:java_lang_Object.h
查看该文件的内容
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class java_lang_Object */
#ifndef _Included_java_lang_Object
#define _Included_java_lang_Object
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: java_lang_Object
* Method: registerNatives
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_java_lang_Object_registerNatives
(JNIEnv *, jclass);
/*
* Class: java_lang_Object
* Method: getClass
* Signature: ()Ljava/lang/Class;
*/
JNIEXPORT jclass JNICALL Java_java_lang_Object_getClass
(JNIEnv *, jobject);
/*
* Class: java_lang_Object
* Method: hashCode
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_java_lang_Object_hashCode
(JNIEnv *, jobject);
/*
* Class: java_lang_Object
* Method: clone
* Signature: ()Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_java_lang_Object_clone
(JNIEnv *, jobject);
/*
* Class: java_lang_Object
* Method: notify
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_java_lang_Object_notify
(JNIEnv *, jobject);
/*
* Class: java_lang_Object
* Method: notifyAll
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_java_lang_Object_notifyAll
(JNIEnv *, jobject);
/*
* Class: java_lang_Object
* Method: wait
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_java_lang_Object_wait
(JNIEnv *, jobject, jlong);
#ifdef __cplusplus
}
#endif
#endif
找到hashCode方法,这里对应的名字为:Java_java_lang_Object_hashCode
.c文件
Object.c文件可以在openjdk查看:http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/7fcf35286d52/src/share/native/java/lang/Object.c
查看该文件的内容
#include <stdio.h>
#include <signal.h>
#include <limits.h>
#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
#include "java_lang_Object.h"
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]));
}
JNIEXPORT jclass JNICALL
Java_java_lang_Object_getClass(JNIEnv *env, jobject this)
{
if (this == NULL) {
JNU_ThrowNullPointerException(env, NULL);
return 0;
} else {
return (*env)->GetObjectClass(env, this);
}
}
这里有hashCode方法对应的代码:{"hashCode", "()I", (void *)&JVM_IHashCode}
,之后就可以在c、c++代码中继续执行了
上面是在openjdk中查找的,在本地安装的jdk中并没有找到相关的文件,有人说都封装在jdk1.8.0_231\jre\bin\server\jvm.dll
里了
总结
java本地方法虽然看不见方法体,但是也有具体的定义,只是不再是java代码了。
参考
- https://blog.csdn.net/calm_encode/article/details/108165294
- https://blog.csdn.net/Arthur_Holmes/article/details/106159633