原文鏈接:http://wetest.qq.com/lab/view/308.html商業(yè)轉(zhuǎn)載請聯(lián)系騰訊WeTest獲得授權(quán)咖熟,非商業(yè)轉(zhuǎn)載請注明出處。
WeTest 導(dǎo)讀
Java 9預(yù)計今年也會正式發(fā)布徒仓,Java 8這個最具變革性且變革性最適于GUI程序的版本,Android終于準(zhǔn)備正式支持誊垢。從自己開發(fā)JavaFx的感受,說一說Java 8應(yīng)該使用的新特性症见。程序員喂走,你應(yīng)該擁抱變化。 (注:本文不講具體語法谋作,具體語法請下載下方分享的《Java 8實戰(zhàn)》芋肠。)
James Lau(google的產(chǎn)品經(jīng)理):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 語言功能的支持遵蚜。經(jīng)過這番改弦易轍帖池,依賴于 Java 類文件格式的現(xiàn)有工具和插件仍可繼續(xù)工作。今后吭净,Java 8 語言功能將得到 Android 構(gòu)建系統(tǒng)的原生支持睡汹。
一、GUI桌面類軟件特點
GUI圖形界面的應(yīng)用程序有幾個特點:
● 基于消息驅(qū)動模型
● 強交互寂殉,實時性要求高
● 用戶觸發(fā)執(zhí)行與用戶觸發(fā)結(jié)束

二囚巴、Lambda表達(dá)式
舉個實際應(yīng)用中的例子,下面這部分的代碼是過濾出某個目錄下所有xml后綴的文件友扰,java 8之前的寫法是這樣子的:

Java 8的寫法

lambda需要解決的一個核心問題啰嗦彤叉,lambda能做的內(nèi)部類都能做。Java是面向?qū)ο蟮恼Z言村怪,不支持方法秽浇。C語言的方法,在java里面可能是一個接口甚负,可能是一個靜態(tài)方法柬焕。listFiles這個方法需要的是一個行為(行為參數(shù)化,更高級的抽象)腊敲,這個行為是name.endsWith(“.xml”)击喂,但是java不支持傳遞行為方法。所以碰辅,java 8之前我們不得不用函數(shù)接口(只包含一個方法的接口懂昂,專有名詞函數(shù)接口)對象的方式來對行為進(jìn)行包裝∶槐觯刻薄的講FileTypeFilter類命名為FilenameFilterActionWrapper更加貼切凌彬。

1沸柔、方法引用
Lambda有一種快捷寫法,方法引用铲敛。之前說褐澎,在Java中定義方法的方式,一種是接口伐蒋,一種是靜態(tài)方法工三,現(xiàn)有的庫中已經(jīng)包含有大量的方法。方法引用先鱼,可以讓我們重用這些方法俭正,讓這些方法像Lambda一樣能夠被傳遞。

GUI程序中的用法,這種寫法Java 8之前焙畔,在JavaFx或者Android程序中都應(yīng)該會大量出現(xiàn)

Java 8之后的寫法應(yīng)該是這樣的
這兩者的差別掸读,解釋起來應(yīng)該是這樣子的。本質(zhì):”直接調(diào)用這個方法”,Lambda或者java 8之前”描述如何調(diào)用這個方法”宏多。你沒必要再去描述如何調(diào)用儿惫,因為都知道該怎么調(diào)用。我們知道GUI程序最基本的設(shè)計時MVC伸但,解決的是視圖和邏輯分離肾请,這幾乎是GUI程序設(shè)計里面最基本的。邏輯處理方法一般并不會包含在控制器的類里面砌烁,而是在邏輯層筐喳,有了方法引用你可以直接與邏輯層的方法相關(guān)聯(lián)。

2函喉、為什么要lambda
● 簡潔的代碼避归,跟利于行為參數(shù)化(高級抽象,if else->參數(shù)化-行為參數(shù)化)
● 預(yù)設(shè)的lambda接口管呵,Predicate梳毙、Consumer、Function等捐下,java 8大量庫支持账锹。如果你不理解lambda,你將不理解大量Java 8的接口坷襟。
● 類型檢查奸柬、類型推斷更優(yōu)
注:寫lambda的時候,參數(shù)一定要有含義婴程,本來就不寫類型了廓奕,再不寫有含義的變量就真的是天書了。
三、CompetableFuture組合式異步編程
一個解析Android apk信息的類桌粉,可能會解析很長一段時間蒸绩,所以需要有超時。Java 5之前的寫法

Java 5的寫法

Java 8

那么CompletableFuture除了少些幾句代碼之外铃肯,它到底有什么好處呢患亿?
● 約定:與設(shè)計模式一樣,這是程序員的一種約定押逼。接口返回CompletableFuture步藕,調(diào)用者一眼就只這是個異步API,也知道如何調(diào)用它
● 同步轉(zhuǎn)異步:配合lambda挑格,幾句話就能完成漱抓。
● 異常傳遞:apkInformation.completeExceptionally(new WeTestRuntimeException(e.getMessage(), e)),其他線程的異乘∑耄可以傳遞過來。GUI程序里面瞬逊,異常通常要轉(zhuǎn)化為用戶的一種視圖显歧。
● 協(xié)調(diào):等待多個異步操作完成合并(如查找多家網(wǎng)站酒店價格,取最小值)确镊,等待多個異步操作中最快的一個完成士骤,異步操作完成后回調(diào)一個函數(shù)(異步操作完成,來個Toast)蕾域。在以前這些協(xié)調(diào)性的功能拷肌,可能需要借助CountDownLatch,CyclicBarrier來完成旨巷。CompletableFuture一步到位
注:CompletableFuture配合Stream可以極大的提高并發(fā)的效率
舉個簡單的上面這個例子返回后的用法:

四巨缘、Stream流處理
Use stream operations to express refined data processing queries.用流Stream以表達(dá)式的方式來完成數(shù)據(jù)處理。我自己的理解是采呐,以數(shù)據(jù)庫的操作方式來完成數(shù)據(jù)的處理若锁。Java 8的Stream內(nèi)置了許多類似于數(shù)據(jù)庫的操作filter、sort斧吐、map又固、reduce等。Stream優(yōu)點:
● 以數(shù)據(jù)庫操作數(shù)據(jù)的方式煤率,專注于如何做這個某個步驟仰冠,表達(dá)式的方式
● 高并發(fā)(看到map、reduce就應(yīng)該能想到了)
注:Stream的寫法的確對原因的思維方式會造成一定的沖擊洋只,不過寫過了,加上有一定數(shù)據(jù)庫使用基礎(chǔ)的話理解起來非常容易。Stream高性能的特點的確感受不深木张,因為處理大量數(shù)據(jù)的情況畢竟是少數(shù)众辨。
五、Optional
A container object which may or may not contain a non-null value.一個可能包含null指的對象包裝器舷礼。null不可避免鹃彻,能避免的是NullPointerException。null最大的罪在于它可以代表任何類型妻献。下面這兩個接口蛛株,不去看你的注釋,我并不知道你是否可能會返回null育拨。在業(yè)務(wù)需求變化如此快的今天谨履,貼切非常容易出現(xiàn)對返回值不做檢查的情況,任何人都會偷懶熬丧。Optional的處理邏輯是笋粟,強迫你去檢查。如果我的返回值是Optional析蝴,這個接口顯式的告訴你可能返回的是null值害捕,這個在GUI程序里面特別常見。

GUI的彈出框用戶可能并不填內(nèi)容內(nèi)容闷畸,返回null尝盼。

所以,Optional的核心思想就是我明確告訴你可能會返回null佑菩,你一定要處理盾沫。所以,現(xiàn)在模塊間提供給其他人的接口殿漠,如果有可能返回為null都要聲明為Optional赴精。Java 8大量的官方接口也都會放回Optional,這個是一定要學(xué)的內(nèi)容绞幌。
Java 8實戰(zhàn):https://share.weiyun.com/075e6cd0f306c706260fb377c38ac90b
近日祖娘,谷歌發(fā)布了安卓8.0開發(fā)者預(yù)覽版。騰訊WeTest立刻在云真機產(chǎn)品中增加了帶有安卓O系統(tǒng)的真機啊奄。
想要率先體驗的用戶可以登錄:http://wetest.qq.com/product/cloudphone
如在使用中有任何疑問渐苏,歡迎聯(lián)系企業(yè)qq:800024531