<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JDK最底層源碼,掌握native用法!

          共 4741字,需瀏覽 10分鐘

           ·

          2022-02-23 13:02

          ?

          ??作者簡(jiǎn)介:大家好,我是小虛竹。Java領(lǐng)域優(yōu)質(zhì)創(chuàng)作者??,CSDN博客專家??,華為云享專家??,掘金年度人氣作者??

          ??技術(shù)活,該賞

          ??點(diǎn)贊 ?? 收藏 ?再看,養(yǎng)成習(xí)慣

          ?

          場(chǎng)景

          有探索欲的同學(xué),應(yīng)該會(huì)跟我一樣,在看JDK源碼時(shí),跟到最后,會(huì)出現(xiàn)native方法,類似下面這個(gè)方法

          ?/**
          ?????*?Gets?the?platform?defined?TimeZone?ID.
          ?????**/

          ????private?static?native?String?getSystemTimeZoneID(String?javaHome);

          看到這個(gè)native ,說(shuō)明已經(jīng)挖到核心了,到了這一步,還是不清楚是怎么獲取系統(tǒng)的默認(rèn)時(shí)區(qū)的,那怎么辦,JDK代碼只能跟到這里。

          轉(zhuǎn)戰(zhàn)OpenJDK,源碼下載方式:https://gitee.com/mirrors/openjdk

          什么是native

          native是一個(gè)計(jì)算機(jī)函數(shù),一個(gè)Native Method就是一個(gè)Java調(diào)用非Java代碼的接口。方法的實(shí)現(xiàn)由非Java語(yǔ)言實(shí)現(xiàn),比如C或C++。

          native的源碼怎么看呢

          以**private static native String getSystemTimeZoneID(String javaHome)**為例

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

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

          如圖
          如圖
          /*
          ?*?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;
          }

          重點(diǎn):調(diào)用不同平臺(tái)相關(guān)的映射函數(shù)

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

          去查找findJavaTZ_md方法時(shí),發(fā)現(xiàn)存在分別在solaris和windows兩個(gè)目錄下。

          如圖

          查了下這兩個(gè)目錄的差別:

          因?yàn)镺penJDK里,Java標(biāo)準(zhǔn)庫(kù)和部分工具的源碼repo(jdk目錄)里,BSD和Linux的平臺(tái)相關(guān)源碼都是在solaris目錄里的。
          原本Sun JDK的源碼里平臺(tái)相關(guān)的目錄就是從solaris和windows這兩個(gè)目錄開(kāi)始的,后來(lái)Unix系的平臺(tái)相關(guān)代碼全都放在solaris目錄下了,共用大部分代碼。

          作者:RednaxelaFX
          鏈接:https://www.zhihu.com/question/58982441/answer/170264788
          來(lái)源:知乎

          「簡(jiǎn)單的理解就是:」

          「window系統(tǒng)下,使用windows目錄下編譯的JDK代碼」

          「unix相關(guān)的平臺(tái)下,使用solaris目錄下編譯的JDK代碼」

          了解不同系統(tǒng)下findJavaTZ_md方法執(zhí)行

          windows系統(tǒng)

          /*
          ?*?Detects?the?platform?time?zone?which?maps?to?a?Java?time?zone?ID.
          ?*/

          char?*findJavaTZ_md(const?char?*java_home_dir,?const?char?*country)
          {
          ????char?winZoneName[MAX_ZONE_CHAR];
          ????char?winMapID[MAX_MAPID_LENGTH];
          ????char?*std_timezone?=?NULL;
          ????int??result;

          ????winMapID[0]?=?0;
          ????result?=?getWinTimeZone(winZoneName,?winMapID);

          ????if?(result?!=?VALUE_UNKNOWN)?{
          ????????if?(result?==?VALUE_GMTOFFSET)?{
          ????????????std_timezone?=?_strdup(winZoneName);
          ????????}?else?{
          ????????????std_timezone?=?matchJavaTZ(java_home_dir,?result,
          ???????????????????????????????????????winZoneName,?winMapID,?country);
          ????????}
          ????}

          ????return?std_timezone;
          }

          注釋寫(xiě)得很清楚,獲取“Time Zones”注冊(cè)表中的當(dāng)前時(shí)區(qū)

          /*
          ?*?Gets?the?current?time?zone?entry?in?the?"Time?Zones"?registry.
          ?*/

          static?int?getWinTimeZone(char?*winZoneName,?char?*winMapID)
          {
          ...
          }

          時(shí)區(qū)的設(shè)置方式:

          如圖

          那時(shí)區(qū)上的選擇值是從哪取到的,上面有說(shuō)了,是在注冊(cè)表中取值

          打開(kāi)注冊(cè)表 :Regedit-->

          計(jì)算機(jī)\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows?NT\CurrentVersion\Time?Zones\

          unix相關(guān)的平臺(tái)

          findJavaTz_md()方法的注釋上寫(xiě)得很清楚了:將平臺(tái)時(shí)區(qū)ID映射為Java時(shí)區(qū)ID

          /*
          ?*?findJavaTZ_md()?maps?platform?time?zone?ID?to?Java?time?zone?ID
          ?*?using?/lib/tzmappings.?If?the?TZ?value?is?not?found,?it
          ?*?trys?some?libc?implementation?dependent?mappings.?If?it?still
          ?*?can't?map?to?a?Java?time?zone?ID,?it?falls?back?to?the?GMT+/-hh:mm
          ?*?form.?`country',?which?can?be?null,?is?not?used?for?UNIX?platforms.
          ?*/

          /*ARGSUSED1*/
          char?*
          findJavaTZ_md(const?char?*java_home_dir,?const?char?*country)
          {
          ????char?*tz;
          ????char?*javatz?=?NULL;
          ????char?*freetz?=?NULL;

          ????tz?=?getenv("TZ");

          #ifdef?__linux__
          ????if?(tz?==?NULL)?{
          #else
          #ifdef?__solaris__
          ????if?(tz?==?NULL?||?*tz?==?'\0')?{
          #endif
          #endif
          ????????tz?=?getPlatformTimeZoneID();
          ????????freetz?=?tz;
          ????}

          ????/*
          ?????*?Remove?any?preceding?':'
          ?????*/

          ????if?(tz?!=?NULL?&&?*tz?==?':')?{
          ????????tz++;
          ????}

          #ifdef?__solaris__
          ????if?(strcmp(tz,?"localtime")?==?0)?{
          ????????tz?=?getSolarisDefaultZoneID();
          ????????freetz?=?tz;
          ????}
          #endif

          ????if?(tz?!=?NULL)?{
          #ifdef?__linux__
          ????????/*
          ?????????*?Ignore?"posix/"?prefix.
          ?????????*/

          ????????if?(strncmp(tz,?"posix/",?6)?==?0)?{
          ????????????tz?+=?6;
          ????????}
          #endif
          ????????javatz?=?strdup(tz);
          ????????if?(freetz?!=?NULL)?{
          ????????????free((void?*)?freetz);
          ????????}
          ????}
          ????return?javatz;
          }

          步驟:

          1、使用< Java home>/lib/tzmappings,。如果沒(méi)有找到"TZ"變量,就進(jìn)行第2步

          2、 ?tz = getPlatformTimeZoneID(); 執(zhí)行Linux特定的映射,如果找到,返回一個(gè)時(shí)區(qū)ID,否則返回null

          【Linux】Centos7修改系統(tǒng)時(shí)區(qū)timezone方式:

          timedatectl
          如圖

          修改時(shí)區(qū)

          timedatectl??set-timezone?Asia/Shanghai
          如圖

          3、對(duì)比/etc/localtime與"/usr/share/zoneinfo目錄下的文件,如果一致,就返回時(shí)區(qū)ID,沒(méi)有則到第4步

          4、返回到GMT


          瀏覽 92
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人伊人综合 | 夸克看成人片一级A片 | 在线观看第一页 | 日本强奸视频 | 日本熟妇在线播放 |