程式設計師要擁抱變化,聊聊Android即將支援的Java 8

程式設計師要擁抱變化,聊聊Android即將支援的Java 8

原文連結:http://wetest.qq.com/lab/view/308.html
商業轉載請聯絡騰訊WeTest獲得授權,非商業轉載請註明出處。

WeTest 導讀

Java 9預計今年也會正式釋出,Java 8這個最具變革性且變革性最適於GUI程式的版本,Android終於準備正式支援。從自己開發JavaFx的感受,說一說Java 8應該使用的新特性。程式設計師,你應該擁抱變化。 (注:本文不講具體語法,具體語法請下載下方分享的《Java 8實戰》。)


James Lau(google的產品經理):We’ve decided to add support for Java 8 language features directly into the current javac and dx set of tools, and deprecate the Jack toolchain. With this new direction, existing tools and plugins dependent on the Java class file format should continue to work. Moving forward, Java 8 language features will be natively supported by theAndroid build system.

我們決定棄用 Jack 工具鏈,改為直接在最新的 javac 和 dx 工具集中增加對 Java 8 語言功能的支援。經過這番改弦易轍,依賴於 Java 類檔案格式的現有工具和外掛仍可繼續工作。今後,Java 8 語言功能將得到 Android 構建系統的原生支援。

一、GUI桌面類軟體特點

GUI圖形介面的應用程式有幾個特點:

● 基於訊息驅動模型

● 強互動,實時性要求高

● 使用者觸發執行與使用者觸發結束
這裡寫圖片描述

二、Lambda表示式

舉個實際應用中的例子,下面這部分的程式碼是過濾出某個目錄下所有xml字尾的檔案,java 8之前的寫法是這樣子的:
這裡寫圖片描述

Java 8的寫法
這裡寫圖片描述

lambda需要解決的一個核心問題囉嗦,lambda能做的內部類都能做。Java是物件導向的語言,不支援方法。C語言的方法,在java裡面可能是一個介面,可能是一個靜態方法。listFiles這個方法需要的是一個行為(行為引數化,更高階的抽象),這個行為是name.endsWith(“.xml”),但是java不支援傳遞行為方法。所以,java 8之前我們不得不用函式介面(只包含一個方法的介面,專有名詞函式介面)物件的方式來對行為進行包裝。刻薄的講FileTypeFilter類命名為FilenameFilterActionWrapper更加貼切。
這裡寫圖片描述

1、方法引用

Lambda有一種快捷寫法,方法引用。之前說,在Java中定義方法的方式,一種是介面,一種是靜態方法,現有的庫中已經包含有大量的方法。方法引用,可以讓我們重用這些方法,讓這些方法像Lambda一樣能夠被傳遞。
這裡寫圖片描述

GUI程式中的用法,這種寫法Java 8之前,在JavaFx或者Android程式中都應該會大量出現
這裡寫圖片描述

Java 8之後的寫法應該是這樣的
這裡寫圖片描述

這兩者的差別,解釋起來應該是這樣子的。本質:”直接呼叫這個方法”,Lambda或者java 8之前”描述如何呼叫這個方法”。你沒必要再去描述如何呼叫,因為都知道該怎麼呼叫。我們知道GUI程式最基本的設計時MVC,解決的是檢視和邏輯分離,這幾乎是GUI程式設計裡面最基本的。邏輯處理方法一般並不會包含在控制器的類裡面,而是在邏輯層,有了方法引用你可以直接與邏輯層的方法相關聯。
這裡寫圖片描述

2、為什麼要lambda

● 簡潔的程式碼,跟利於行為引數化(高階抽象,if else->引數化-行為引數化)

● 預設的lambda介面,Predicate、Consumer、Function等,java 8大量庫支援。如果你不理解lambda,你將不理解大量Java 8的介面。

● 型別檢查、型別推斷更優

注:寫lambda的時候,引數一定要有含義,本來就不寫型別了,再不寫有含義的變數就真的是天書了。

三、CompetableFuture組合式非同步程式設計

一個解析Android apk資訊的類,可能會解析很長一段時間,所以需要有超時。
Java 5之前的寫法
這裡寫圖片描述

Java 5的寫法
這裡寫圖片描述

Java 8
這裡寫圖片描述

那麼CompletableFuture除了少些幾句程式碼之外,它到底有什麼好處呢?

● 約定:與設計模式一樣,這是程式設計師的一種約定。介面返回CompletableFuture,呼叫者一眼就只這是個非同步API,也知道如何呼叫它

● 同步轉非同步:配合lambda,幾句話就能完成。

● 異常傳遞:apkInformation.completeExceptionally(new WeTestRuntimeException(e.getMessage(), e)),其他執行緒的異常可以傳遞過來。GUI程式裡面,異常通常要轉化為使用者的一種檢視。

● 協調:等待多個非同步操作完成合並(如查詢多家網站酒店價格,取最小值),等待多個非同步操作中最快的一個完成,非同步操作完成後回撥一個函式(非同步操作完成,來個Toast)。在以前這些協調性的功能,可能需要藉助CountDownLatch,CyclicBarrier來完成。CompletableFuture一步到位

**注:**CompletableFuture配合Stream可以極大的提高併發的效率

舉個簡單的上面這個例子返回後的用法:
這裡寫圖片描述

四、Stream流處理

Use stream operations to express refined data processing queries.用流Stream以表示式的方式來完成資料處理。我自己的理解是,以資料庫的操作方式來完成資料的處理。Java 8的Stream內建了許多類似於資料庫的操作filter、sort、map、reduce等。
Stream優點:

● 以資料庫運算元據的方式,專注於如何做這個某個步驟,表示式的方式

● 高併發(看到map、reduce就應該能想到了)
這裡寫圖片描述

舉個用法的例子,業務時獲取所有線上的可測試的手機:
這裡寫圖片描述

**注:**Stream的寫法的確對原因的思維方式會造成一定的衝擊,不過寫過了,加上有一定資料庫使用基礎的話理解起來非常容易。Stream高效能的特點的確感受不深,因為處理大量資料的情況畢竟是少數。

五、Optional

A container object which may or may not contain a non-null value.一個可能包含null指的物件包裝器。null不可避免,能避免的是NullPointerException。null最大的罪在於它可以代表任何型別。下面這兩個介面,不去看你的註釋,我並不知道你是否可能會返回null。在業務需求變化如此快的今天,貼切非常容易出現對返回值不做檢查的情況,任何人都會偷懶。Optional的處理邏輯是,強迫你去檢查。如果我的返回值是Optional,這個介面顯式的告訴你可能返回的是null值,這個在GUI程式裡面特別常見。
這裡寫圖片描述

GUI的彈出框使用者可能並不填內容內容,返回null。
這裡寫圖片描述

所以,Optional的核心思想就是我明確告訴你可能會返回null,你一定要處理。所以,現在模組間提供給其他人的介面,如果有可能返回為null都要宣告為Optional。Java 8大量的官方介面也都會放回Optional,這個是一定要學的內容。

Java 8實戰:https://share.weiyun.com/075e6cd0f306c706260fb377c38ac90b


近日,谷歌釋出了安卓8.0開發者預覽版。騰訊WeTest立刻在雲真機產品中增加了帶有安卓O系統的真機。

想要率先體驗的使用者可以登入:http://wetest.qq.com/product/cloudphone

如在使用中有任何疑問,歡迎聯絡企業qq:800024531