最近開始看
王森先生的《java深度歷險》,從我一借到這本書就愛不釋手,書裡的內容非常吸引人。可以說這本書有助於我們對Java程序運行過程有更深的理解。所以我將記錄一些書中的重要結論,供大家參考,也作為自己的筆記。
第一章:
我們的機器裡面至少有兩套jre,一套在%JAVA_HOME%/jre,一套在%HOME%/Program Files/Java/jre1.x.x,那麼當我們在命令行輸入Java xxx的時候會按照下面的邏輯來尋找適合的jre來執行程序:
1. 當前目錄
2. 父目錄下的jre子目錄
3. 查詢注冊表裡面的jre
所以我們在配置環境變量的時候一定要注意。
第二章:
構造類的時候可以動態地載入內存,這樣可以從一定程度上提高效率,所有類的載入都需要有ClassLoader。
顯式的動態載入類有兩種方法:一種是Class.forName(),一種是ClassLoader.loadClass(),它們得到的都是Class對象,也就是相應類的元數據,然後調用newInstance()方法就可以構造這個類的對象了。這兩種方法的原理都是有一個ClassLoader來載入類。我們可以直接使用默認的CLassLoader來載入類,也可以實現自己的ClassLoader(URLClassLoader就是一個例子)來載入。
而書中介紹的重點是默認的CLassLoader載入類的原理。JVM有三個ClassLoader,分別是Bootstrap Loader(這個轉載器是C++寫的,直接與JVM打交道),ExtClassLoader,AppClassLoader。默認情況下先請求AppClassLoader來搜索class文件,AppClassLoader再向其parent類ExtClassClassLoader請求,ExtClassClassLoader再請求其parent“類”Bootstrap Loader搜索。如果父裝載器在其搜索路徑裡找不到class文件就再由子裝載器搜索,如果一直到AppClassLoader找不到就會拋出NoClassDefFoundError。這就是ClassLoader HIErarchy,簡而言之就是所有轉載請求一直發送到Bootstrap Loader,然後找不到才由子裝載器裝載。
下面介紹3個轉載器的搜索路徑:
Bootstrap Loader:System.getProperty(“sun.boot.class.path”);得到,默認是jre/classes。修改的方法是執行程序的時候使用Java -Dsun.boot.class.path=yourPath XXX
ExtClassLoader:System.getProperty(“java.ext.dirs”):得到,默認是jre/lib/ext。修改的方法是執行程序的時候使用java -DJava.ext.dirs=yourPath XXX
AppClassLoader:System.getProperty(“java.class.path”);得到,默認就是環境變量中的CLASSPATH。修改方法一個是修改環境變量,一個執行程序的時候使用Java –classpath yourPath XXX
了解了這些以後我們就可以對類的裝載有一定了解,以後放置第三方jar包的時候就能清楚放在什麼目錄最合適。當然書裡也說了JDBC驅動和JNDI的類裝載涉及ContexClassLoader,它是以上原理不一樣的,書裡也沒有介紹。
第三章:
通過一個創建Word文檔的例子,介紹了JNI技術。
由於Java程序都是在jvm基礎上執行的,所以有很多與操作系統底層聯系緊密的功能都難以實現。我們就可以用native關鍵字修飾一個本地方法,而這個方法是由其他語言來實現。這樣我們可以調用Windows的dll和Unix/Linux的so文件來和操作系統底層交互。
to be continued...