Java9發布已經有一年了,跟Java8相比,從目錄對比就看得出來差別相當大。
實際上Java9最大的變化就是JDK模塊化(Modular)。
那么,模塊化的目的是什么呢?
官方的說法是:
之前版本的Java存在一些問題:
1、JDK和JRE作為一個整體部署,體積太大(JDK8只是rt.jar一個包就超過60MB)。體積大有如下缺點:
(1)下載慢,部署慢。
(2)內存較小的設備無法部署。這跟Java從誕生時的口號Write once , Run anywhere不符。
(3)大量部署在雲端,累計占用的內存非常可觀。
2、訪問控制粒度不夠細。
所有public關鍵字定義的屬性或者方法,在任何地方都可以被調用,這影響了代碼的封裝性。例如在import了sun.*之后,sun.*下面大量用不着的API也暴露出來了(最直觀的例子就是使用IDE時,在對象名后面輸入點“.”自動會彈出所有public的屬性和方法清單以供選擇)。
另外,之前的權限控制針對的是類與類之間的關系,模塊化針對的是組件之間的控制。模塊化的目標之一是,利用一組邏輯獨立的組件搭建出完整的系統。
3、Dependency Hell。
依賴地獄是一個詼諧的說法,指的是由Java類加載機制的特性引發的一系列問題,包括JAR包沖突、運行時類缺失。
為了解決以上這些問題,Java9引入了模塊系統JPMS。
這里有個問題需要明確下,JPMS和OSGI的模塊化還是有區別的,可以參考文章《Java 9,OSGi和模塊化的未來》。
【說明】
1、JAR包沖突
有時classpath中不同的JAR包會包含限定名完全相同的類。造成這種現象的原因有很多,例如一個Fat JAR包含了某個類A的版本v1,另一個Fat JAR包含了該類A的另一個版本v2,這時就會導致同一個類的兩個版本沖突。
JVM的類加載機制會從classpath中第一個包含某個類的JAR包里加載該類,這個被加載的類將會“屏蔽”該類的其他版本(可能真正需要的卻是這個版本),使這些類變得不可用。這樣會導致程序的行為不是我們預想的那樣,結果可能很糟。
2、運行時類缺失(這是我自己的說法)
有些依賴如第三方JAR包,Java運行時系統只有在真正需要訪問這些JAR包時才能檢測到它所依賴的某些類找不到。這時運行時系統將會拋出NoClassDefFoundError異常,進而導致正在運行的應用程序崩潰。
3、Fat JAR
Fat JAR是將所有依賴和資源文件都打包成一個JAR包,它可能包含了另一個它依賴的JAR包。
【參考】
https://www.jianshu.com/p/053a5ca89bbb
https://my.oschina.net/lt0314/blog/1544711
http://udn.yyuap.com/forum.php?mod=viewthread&tid=113385
https://stackoverflow.com/questions/373193/what-is-classpath-hell-and-is-was-it-really-a-problem-for-java