(零):要探索JDK的核心底层源码,那必须掌握native用法(一)

Bald_eagle
发布于 2022-6-7 17:08
浏览
0收藏

 

场景
有探索欲的同学,应该会跟我一样,在看JDK源码时,跟到最后,会出现native方法,类似下面这个方法

 /**
     * Gets the platform defined TimeZone ID.
     **/
    private static native String getSystemTimeZoneID(String javaHome);

看到这个native ,说明已经挖到核心了,到了这一步,还是不清楚是怎么获取系统的默认时区的,那怎么办,JDK代码只能跟到这里。

转战OpenJDK,源码下载方式:https://gitee.com/mirrors/openjdk

什么是native
native是一个计算机函数,一个Native Method就是一个Java调用非Java代码的接口。方法的实现由非Java语言实现,比如C或C++。

native的源码怎么看呢
以**private static native String getSystemTimeZoneID(String javaHome)**为例

getSystemTimeZoneID方法所在的package java.util.TimeZone;

如图所示,找到TimeZone.c下的getSystemTimeZoneID方法

(零):要探索JDK的核心底层源码,那必须掌握native用法(一)-鸿蒙开发者社区

 如图

(零):要探索JDK的核心底层源码,那必须掌握native用法(一)-鸿蒙开发者社区
 如图

/*
 * Gets the platform defined TimeZone ID
 */
JNIEXPORT jstring JNICALL
Java_java_util_TimeZone_getSystemTimeZoneID(JNIEnv *env, jclass ign,
                                            jstring java_home, jstring country)
{
    const char *cname;
    const char *java_home_dir;
    char *javaTZ;

    if (java_home == NULL)
        return NULL;

    java_home_dir = JNU_GetStringPlatformChars(env, java_home, 0);
    if (java_home_dir == NULL)
        return NULL;

    if (country != NULL) {
        cname = JNU_GetStringPlatformChars(env, country, 0);
        /* ignore error cases for cname */
    } else {
        cname = NULL;
    }

    /*
     * Invoke platform dependent mapping function
     */
    javaTZ = findJavaTZ_md(java_home_dir, cname);

    free((void *)java_home_dir);
    if (cname != NULL) {
        free((void *)cname);
    }

    if (javaTZ != NULL) {
        jstring jstrJavaTZ = JNU_NewStringPlatform(env, javaTZ);
        free((void *)javaTZ);
        return jstrJavaTZ;
    }
    return NULL;
}

 

重点:调用不同平台相关的映射函数

  /*
     * Invoke platform dependent mapping function
     */
    javaTZ = findJavaTZ_md(java_home_dir, cname);

去查找findJavaTZ_md方法时,发现存在分别在solaris和windows两个目录下。

(零):要探索JDK的核心底层源码,那必须掌握native用法(一)-鸿蒙开发者社区

 如图

查了下这两个目录的差别:

因为OpenJDK里,Java标准库和部分工具的源码repo(jdk目录)里,BSD和Linux的平台相关源码都是在solaris目录里的。
原本Sun JDK的源码里平台相关的目录就是从solaris和windows这两个目录开始的,后来Unix系的平台相关代码全都放在solaris目录下了,共用大部分代码。

作者:RednaxelaFX
链接:https://www.zhihu.com/question/58982441/answer/170264788
来源:知乎

 

「简单的理解就是:」

「window系统下,使用windows目录下编译的JDK代码」

「unix相关的平台下,使用solaris目录下编译的JDK代码」

 

文章转自公众号:小虚竹JAVA之术

分类
标签
已于2022-6-7 17:08:10修改
收藏
回复
举报
回复
    相关推荐