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 爲基礎的應用有幫助的插件啥的 ~~