在 Eclipse 中跟蹤 JDK 局部變量

jdk 無疑在開發過程中佔有巨大作用,無論是開發需要,還是源碼學習需要,能夠方便進行跟蹤調試會給整個過程帶來極大的愉悅感~~

這裏我舉個李子

MyMap.java

        ...

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("theKey", "theValue");
    }

        ...

這裏我們可以看到對於 HashMap 進行了 put 的調用,那麼內部是怎麼搞的尼,請下看

HashMap.java

        ...

    public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        // local variables
        int hash = hash(key);
        // local variables
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

        ...

源碼中,有幾處都是用局部變量的,可惜如果我們就這樣貿然進去,人家會不舒服就不會將祕密告訴你了 -_-|||

下載過 jdk 包的帥哥靚妹應該都還是清楚的哈,曝個照先

這裏寫圖片描述

這是一個完整的 jdk 包,可以看到是目前 7 系列最新的喲~~,直接給個地址吧,想知道包的含義就去看看,原版

看到那個 rt.jar 了嗎?這個就是重中之重啦,人家的全稱是 ~~ runtime.jar ~~ 這麼理解吧,有麼有覺得很吊。也就是說你小樣兒用的各種 Map/Set/Array… 啥啥的都是在人家地盤上轉。

所以呢,要想人家掏心窩,首先我們就要主動出擊,出其不備,一舉拿下。其實最直接的想法就是,這貨不就是 Oracle 給打包出來的麼,爲啥就不能痛快點呢,讓咱們也好好用用呀,還非得留一手啊~~如果這麼想那就太沒人情味了,怎麼說人家也是戰鬥機中的巨無霸啊,凡事會考慮個一二三的哇,且聽咱道來。

翻譯過來的~~

rt.jar 包含所有與 Java SE 核心 API 相對應的 RunTime 類

由於所有在 rt.jar 中的類對 JVM 來說都是 “親戚”,當 JVM 在載入這些個類時它們會有特例不會進行各種 check。這個做法也有許多的性能方面的原因。這些 classes 是由 The Primordial Class Loader 載入的,這就是爲什麼在別的 jars/classes 需要被 JVM check 的時候 rt.jar 能夠避免這些 basic security checks 了。果然是親生的了~~

果然非同一般呀, 不過呢,爲了咱廣大的碼農還是給出了 src.zip。在我們沒有動過 rt.jar 的時候,裏邊類是由源代碼通過去掉調試信息的方式編譯的,這就是爲啥咱們看不到局部變量的值了,詳細內容各位自行查找吧。

很明顯我們接下來就去實現我們本文的重點吧,貌似廢話挺多的~~

咱是在 Ubuntu 上玩的哈,先再個給已經安裝好的靚照

這裏寫圖片描述

嗯。和下載的其實差不多吧~~

上邊也提過,我們在開發過程中使用到的 JDK 都是來自於 rt.jar 的,那麼我們只要將 src.zip 中的全部或者自己需要的進行編譯,然後打包放好那豈不是就可以了麼~~

有這麼幾個步驟

  • 創建編譯的相關目錄
  • 拷貝rt.jar
  • 生成需要編譯的類列表文件
  • 編譯
  • 打包編譯好的類
  • 放到相應的位置
  • 試試看~~

咱是以自己的環境爲準哈,帥哥靚妹們可以套套步驟,整體方法,命令差別不大

搭建編譯環境

上圖
我們先到 JDK 安裝路徑下找到倆東西

  • src.zip
    這裏寫圖片描述
    那個紅紅的就是啦,當然我們是可以直接從下載的壓縮包裏搞出來,但是還是建議在自己安裝的 JDK 裏邊吧,也方便嘛,而且版本絕對不會出問題~~

  • rt.jar
    這裏寫圖片描述
    最右邊那紅紅噠~~

然後在咱的 home 創建瞭如下的目錄結構,以及 copy 過來的倆東西

  • 目錄 jdk(這個隨意)
    這裏寫圖片描述
    在此文件夾下還有一個 out 和 src 目錄,分別是編譯後存放類的目錄

  • 目錄 src(同上)
    這裏寫圖片描述

可以看到這裏邊有三個目錄 java/javax/org,分別就對應到基礎類的頂級包,當然也是可以把所有的都給解壓出來哈

咦,有沒有發現這裏多了一個東西呢,files.txt,對,這就是所以需要進行編譯的文件相對位置文件咯

來,局部圖片
這裏寫圖片描述

感覺是不是很吊的樣子,咱一直對這種密密麻麻的東西感覺很興奮呀,變態~~

這個文件的生成還是比較簡單的,至少在 Ubuntu 或者是 Linux/Unix 系列下

 find -name *.java > files.txt

好,這樣文件就生成了~~

關鍵一步,在此獻上

javac -J-Xmx1024m -J-Xms16m -sourcepath /home/ice/temp/jdk/src -d /home/ice/temp/jdk/out -cp /home/ice/temp/jdk/rt.jar -g @files.txt >> log.txt 2>&1

大家看看應該還是比較容易理解哈

  • -sourcepath
    咱需要編譯的類所在目錄

  • -d
    生成的編譯文件存放目錄

  • -cp(classpath)
    運行時指定的環境,可是爲啥要用到 rt.jar 尼?不是要把他給費了麼?嗯,這個其實只要看看 src.zip 就大概懂了,把裏邊的內容和 rt.jar 中的進行比較一下
    這裏寫圖片描述
    在 src.zip 中是不是沒有發現 sun 呢,對啦,就不給咱,那也沒辦法,而她卻是重中之重啊,讓我們默默的把她帶上吧~~
    提一句,在 Ubuntu 下,最好要將 rt.jar 拷貝出來,這裏邊有權限問題,煩

  • -g
    這哥麼兒就是說,把調試信息給咱們塞進去哈,謝啦~~

  • @files.txt
    這個就是剛剛我們生成的需編譯類類表啦

  • -J
    這個麼,一些 jvm 運行參數配置咯~~

就這麼一運行,哦靠,咱麼編譯成功啦
這裏寫圖片描述

這幾個就是咱麼的好夥伴啦,不好意思,多添了倆包進去^_^

繼續

jar cf0 rt_debug.jar *

這個呢就是把這些個給打包咯~~
這裏寫圖片描述

緊接着要幹啥呢,其實我們基本上及完成了 99% 啦,最後就是看把她放哪兒了

這裏寫圖片描述

和 rt.jar 處於同一個目錄下,與標準的比比,會發現多了一個目錄

endorsed

對,就是她了
這裏寫圖片描述
我們只要把咱麼地寶貝 rt_debug.jar copy 過來就好啦 ^_^

惡,怎麼驗證呢,簡單呀,調試上邊的代碼,跟蹤進行去看看唄~~

這裏寫圖片描述

看到沒,看到沒,局部變量出現啦~~

我要說,謝謝觀看 ^_^

有錯誤/有建議/有不爽,還請各位帥哥靚妹 留言哈~~

~~~
給大家個工具,不過現在用的帥哥靚妹挺多了吧, STS(Spring Tool Suit) 一個基於 Eclipse,而且集成了諸多對於開發 Spring 爲基礎的應用有幫助的插件啥的 ~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章