再談Java9模塊化
在之前已經(jīng)提到了作為java9最重要的特性就是模塊化帚戳。有了模塊化java9變得更輕量級。在編譯運行的時候可以更一步的節(jié)省資源全封。上一篇文章中提到了java9模塊化的一些keyword频鉴。介紹的不全面,下面來補充介紹一下模塊化中的keyword
exports
exports PackageName [to ModuleName {, ModuleName}] ;
定義對外暴露的包名(允許外部模塊在運行
或編譯
期間訪問該包下面的所有public
永高、protect
文件或變量方法隧土,而且允許外部模塊通過反射可以訪問到該包下的public
提针、protect
文件或者變量方法)。還可以指定具體to
哪個模塊曹傀。這樣就可以縮小對外暴露范圍辐脖。只有指定的模塊才可以使用該包下面的文件。否則編譯報錯皆愉。這樣就可以對底層的模塊進行保護嗜价,避免上層調(diào)用。
opens
opens PackageName [to ModuleName {, ModuleName}] ;
定義對外打開的包名(允許外部模塊在運行
期間訪問該包下的所有public
幕庐、protect
文件或變量方法久锥,且允許外部模塊通過反射訪問的該包下的所有類型的資源)。所以opens
比exports
開放的權(quán)限大异剥,但是要通過反射去獲取瑟由。同樣也可以定義具體to
哪個模塊,指定授權(quán)該模塊可訪問冤寿。否則運行報錯歹苦。
uses
uses TypeName ;
定義消費的服務(wù)類型《搅可以是一個具體的類暂氯,也可以是一個借口,或者一個注解類(不能是枚舉)亮蛔。然后定義后通過 java.util.ServiceLoader#load(Class)
方法可以加載到該服務(wù)的具體實現(xiàn)類痴施。然后循環(huán)迭代調(diào)用。
provides
provides TypeName with TypeName {, TypeName} ;
定義服務(wù)提供者究流。結(jié)合上面的uses
使用辣吃。eg:在a
模塊中我定義了接口A
,且定義了A
的實現(xiàn)AImpl
芬探,然后我在b
模塊中requires a; use A;
這樣我在b
模塊中使用ServiceLoader
加載A.class的時候就可以獲得AImpl
實體神得。也可以在b
模塊中新增A
的實現(xiàn)BImpl
,然后在b
模塊文件中定義provides A with BImpl
偷仿。這樣ServiceLoader
就可以獲取到兩個不同的實現(xiàn)(可以根據(jù)實際需要自定義選取哪個實現(xiàn))哩簿。uses
和provides
是模塊化里面對接口的增強。
eg:
module A
public interface ITest {
void t();
}
public class ATestImpl implements ITest {
@Override
public void t() {
System.out.println("ATestImpl");
}
}
module A {
exports a to B;
provides a.ITest with a.ATestImpl;
}
module B
public class TestImpl implements ITest {
@Override
public void t() {
System.out.println("TestImpl");
}
}
public class BTestImpl implements ITest {
@Override
public void t() {
System.out.println("BTestImpl");
}
}
module B {
requires A;
provides a.ITest with b.TestImpl;
uses a.ITest;
}
public static void main(String[] args) {
ServiceLoader<ITest> load = ServiceLoader.load(ITest.class);
load.stream().forEach(t -> t.get().t());
}
我在兩個模塊中定義了三個實現(xiàn)酝静。但是我只聲明了兩個provides
在module-info
中节榜,最終執(zhí)行結(jié)果為
ATestImpl
TestImpl
java9的一些小結(jié)
- 模塊化。簡化java運行依賴别智,解耦jar包的依賴宗苍,增強封裝特性等。
- 允許在接口中定義并實現(xiàn)私有方法』淇撸可以提供給接口的默認方法使用(
default,static
)让歼,這樣多個默認方法且實現(xiàn)代碼有重復(fù)可以通過這種方式重構(gòu),使代碼變得簡潔丽啡。 - 更方便的集合構(gòu)建方式谋右。可以直接使用
List.of(1,2,3,4)
這種方式來生成集合补箍。系統(tǒng)會根據(jù)默認值推斷出集合的類型倚评。生成的集合是java.util.ImmutableCollections
不可變的。 - Stream新增
takeWhile,dropWhile,ofNullable
等方法馏予。使stream操作流更靈活天梧。還支持Optional轉(zhuǎn)Stream - java工具大殺器
JShell
,直接在jdk9的bin目錄下執(zhí)行.jshell
就可以進入JShell腳本工具里。直接運行java代碼霞丧∧馗冢可以拋開繁瑣的包名類名main方法等。你甚至只需要執(zhí)行一段可執(zhí)行的代碼即可蛹尝,不需要寫方法后豫。 - 其它還有很多,比如貨幣的支持突那,新的httpclient挫酿,輕量級json處理,簡化進程API等等愕难。