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代码了。

参考

  1. https://blog.csdn.net/calm_encode/article/details/108165294
  2. https://blog.csdn.net/Arthur_Holmes/article/details/106159633
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值