像是:
Default and static interface methods
Repeatable annotations
Lambda expressions 與 Method References (這兩項可向下支援到 API level 23 以下)
(其他支援的 Java 8 API 請參考文末連結)
而要使用這些支援必須認識一下 Jack
Jack (Java Android Compiler Kit) 是 Android 新的 toolchain
用來把 java code 編譯成 Android dex bytecode
Jack 使用 Java 1.7 並移植了一些新功能
不但是 Open source,還縮短編譯時間
而這個 toolchain 取代了之前的 javac, ProGuard, dx 等工具
傳統 javac 工具鏈: javac (.java --> .class) --> dx (.class --> .dex)
新的 Jack 工具鏈: Jack (.java --> .jack --> .dex)
Jack 是 Android M 的 default build toolchain
所以不用下任何特殊的 command 就可以使用
順便認識認識 Jack Intermediate Library Linker (Jill)
它負責的是把 jar 檔轉換成新的 lib 格式 (.jack)
在 build.gradle (app) 使用 Jack 的方式
android { ...(省略) defaultConfig { ...(省略) jackOptions{ enabled true } } compileOptions { targetCompatibility 1.8 sourceCompatibility 1.8 } ...(省略) }完成以上設定後就可以在專案內使用 lambda 了
同場加映:Lambda 表達式簡介
匿名類別 Anonymous Classes 常被使用於作為一個參數傳遞到 method 裡
但匿名類別(特別是只有一個方法的匿名類別) 寫起來常感覺有些繁瑣
而 Lambda Expressions 對於簡化只有單一方法的類別就可以發揮優點
Lambda 表達式語法:
* 逗號分隔的的參數
* 箭頭標記( -> )
* 表達式主體
- 若使用單行表達式則回傳結果值,或是直接使用 return,不過 return statement 不是表達式,如果 method 不是回傳 void 則 statement 需使用大括號( { } )
例如如果我們有一個 printPersons 方法,傳入 List<Person> 及 CheckPerson 介面的實體(其中有 test 方法)
可以輸出通過條件的 Person 訊息
public static void printPersons( List<Person> roster, CheckPerson tester) { for (Person p : roster) { if (tester.test(p)) { p.printPerson(); } } }實際呼叫時 code 是像這樣:
printPersons( roster, new CheckPerson() { public boolean test(Person p) { return p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25; } } );改寫成 lambda 之後:
printPersons( roster, (Person p) -> p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25 );
相關資料:
android developers - Java 8 Language Features
Jack (Java Android Compiler Kit)
沒有留言:
張貼留言