AS3.0中的J8新特性

今天google官方放出了期待已久的AS3.0正式版,加入了很多新特性碴萧,支持kotlin,java8末购,編譯速度更快等等破喻,想必很多kotlin小迷弟,小迷妹們已經(jīng)歡呼雀躍盟榴。然鵝曹质,菜雞如我,不會(huì)使用kotlin擎场。只能研究一下作為android開(kāi)發(fā)者在AS3.0中可以使用到的java8新特性羽德。

官方對(duì)于AS中J8新特性的頁(yè)面如下Use Java 8 Language Features(請(qǐng)自備紅杏)

附上gradle-4.1-all.zip地址

配置Java8

首先需要拋棄之前的第三方插件

Android Studio為使用某些Java 8語(yǔ)言功能和使用它們的第三方庫(kù)提供內(nèi)置支持。迅办,默認(rèn)工具鏈通過(guò)desugar在javac編譯器的輸出上執(zhí)行字節(jié)碼轉(zhuǎn)換來(lái)實(shí)現(xiàn)新的語(yǔ)言特性宅静。

默認(rèn)工具鏈

在3.0之前,相信很多小伙伴為了嘗試java8的新特性站欺,會(huì)使用第三方的插件來(lái)使用lambda姨夹,如:Jack, Retrolambda, 或 DexGuard,AS3.0將對(duì)其不再提供支持矾策,如果as檢測(cè)到你繼續(xù)使用這些插件磷账,as將繼續(xù)使用第三方插件,而不使用默認(rèn)的工具鏈蝴韭。

刪除Jack支持

jackOptionsbuild.gradle刪除

  android {
      ...
      defaultConfig {
      ...
    // 刪除此代碼塊
        jackOptions {
            enabled true
              ...
        }
}

刪除Retrolambda

請(qǐng)從項(xiàng)目級(jí)build.gradle文件中刪除Retrolambda依賴關(guān)系

buildscript {
  ...
   dependencies {
      // 刪除此依賴
      classpath 'me.tatarka:gradle-retrolambda:<version_number>'
   }
}

并刪除每個(gè)moudle下的build.gradle文件中Retrolambda引入

//刪除
apply plugin: 'me.tatarka.retrolambda'
//刪除(如果有的話)
retrolambda {
    jvmArgs '-Xmx2048m'
}

設(shè)置Java8

build.gradle文件下android節(jié)點(diǎn)添加如下

android {
  ...
  //將項(xiàng)目的源和目標(biāo)兼容性值設(shè)置為Java 8
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

AS中的Java8新特性

放一張官方的資料圖:

image.png

可以看到新版AS中指支持部分Java8的新特性够颠,且有一部分還有minSdkVersion限制。接下來(lái)榄鉴,我們對(duì)其比較常用的進(jìn)行講解:

Lambda

相信大家已經(jīng)lambda已經(jīng)非常熟悉履磨,這里我們不講語(yǔ)法,講點(diǎn)別的需要注意的地方庆尘。

與匿名內(nèi)部類的區(qū)別

lambda大家看作是一種匿名內(nèi)部類剃诅,但實(shí)際卻與匿名內(nèi)部類是有區(qū)別的,

  • lambda編譯完成之后驶忌,使用的是J7新增的指令invokedynamic來(lái)表示矛辕,具體的實(shí)現(xiàn)不體現(xiàn)在字節(jié)碼文件中笑跛,由虛擬機(jī)進(jìn)行翻譯lambda的具體執(zhí)行策略,以便于后續(xù)JDK版本優(yōu)化此語(yǔ)法特性的策略聊品,同時(shí)可以很大程度上減少字節(jié)碼的文件的大小和數(shù)量飞蹂,分配方式類似于java.lang.invokeMethodHandle中的動(dòng)態(tài)調(diào)用方法(具體請(qǐng)百度)。目前lambda的具體執(zhí)行方式還是與匿名內(nèi)部類差不多的策略翻屈,據(jù)說(shuō)oracle在以后的版本更新中會(huì)優(yōu)化分配測(cè)羅陈哑,選用MethodHandle
  • 而匿名內(nèi)部類方式生成新類伸眶,新建一個(gè)標(biāo)有$xx.class的文件惊窖。

分類

lambda表達(dá)式的類型是一種特殊的接口,這種接口只有一個(gè)抽象方法厘贼,成為函數(shù)接口界酒。

在J8中,lambda表達(dá)式傾向于函數(shù)式編程嘴秸,根據(jù)其輸入與返回類型不同毁欣,分為幾種類型的函數(shù)接口,下面是系統(tǒng)提供的一組函數(shù)式接口類型赁遗,并以Rxjava的操作符舉例:

接口 參數(shù) 返回類型 說(shuō)明
Predicate<T> T boolean 判斷型函數(shù)署辉,filter
Consumer<T> T void 消費(fèi)型函數(shù)族铆,subcribe
Function<T,R> T R 轉(zhuǎn)換型函數(shù)岩四,map
Supplier<T> None T 生產(chǎn)型函數(shù),create
UnaryOperator<T> T T Function的特殊情況
BinaryOperator<T> (T,T) T (二元)多元運(yùn)算哥攘,zip

我們可以同過(guò)自定義接口進(jìn)行使用剖煌,如android的View.OnclickListener極為消費(fèi)性函數(shù)。

注意莉掂,在自定義函數(shù)接口時(shí)胳岂,站在用途的角度來(lái)考慮蚓耽,為了區(qū)分普通接口與函數(shù)接口的區(qū)別,建議自定的函數(shù)接口都應(yīng)該加上@FunctionalInterface注解茉兰。該直接會(huì)強(qiáng)制編譯器檢查一個(gè)接口是否符合函數(shù)接口的標(biāo)準(zhǔn)。如果該注釋添加給一個(gè)枚舉類型欣簇,類或者接口包含不止一個(gè)抽象方法规脸,編譯器就會(huì)報(bào)錯(cuò)。這對(duì)我們規(guī)范化代碼有很大的幫助熊咽。

重載解析

莫鸭,在運(yùn)行過(guò)程中,會(huì)根據(jù)横殴,java中可以重載方法被因,造成多個(gè)方法會(huì)有相同的方法名,但簽名卻不一樣。這在推斷類型是會(huì)帶來(lái)問(wèn)題梨与,因?yàn)橄到y(tǒng)可能會(huì)推斷出多種方法類型堕花。當(dāng)lambda表達(dá)式作為參數(shù)時(shí),當(dāng)出現(xiàn)重載情況時(shí)粥鞋,這時(shí)航徙,

java會(huì)挑出最具體的類型。

看一個(gè)例子:

static interface IntergerBifunciton extends BinaryOperator<Integer>{
    }
    public  void overloadedMethoe(BinaryOperator<Integer> l){
    }
    public  void overloadedMethoe(IntergerBifunciton l){
    }

接口IntergerBifuncitonBinaryOperator的子接口陷虎,在調(diào)用overloadedMethoe((x,y)->x+y)的時(shí)候到踏,虛擬機(jī)會(huì)選用最具體的類型

再看一個(gè)無(wú)法推斷哪個(gè)更具體類型的例子:

    static interface Intergerfunciton{
        public boolean test(int x);
    }
    public  void overloadedMethoe(Predicate<Integer> l){
    }
    public  void overloadedMethoe(Intergerfunciton l){
    }

我們使用overloadedMethoe((x)->true);調(diào)用的時(shí)候尚猿,會(huì)出現(xiàn)錯(cuò)誤:

模糊調(diào)用

這是因?yàn)槲迅澹幾g器無(wú)法推斷出哪種類型更具體 更適合方法的參數(shù),故報(bào)錯(cuò)凿掂。我們?cè)谌粘i_(kāi)發(fā)中應(yīng)該避免出現(xiàn)這種情況伴榔。

Default and static interface methods(默認(rèn)方法和靜態(tài)接口方法)

  • 默認(rèn)方法
    java8相比之前最大的改動(dòng)無(wú)疑是對(duì)集合類的改動(dòng)和添加StreamAPI(minSdkVersion為24可用),用于在集合類中更方便的進(jìn)行函數(shù)是編程庄萎,大家可以把StreamAPI看成類似Rxjava的類庫(kù)踪少,用以方便的對(duì)數(shù)據(jù)進(jìn)行變換。(同樣的糠涛,Stream也有很多類似Rxjava操作符的方法援奢,比如filter,map忍捡,toList集漾,flatmap等等,使用方法大同小異)砸脊。

java為Collection接口添加了stream方法(見(jiàn)下圖)具篇,但是問(wèn)題出現(xiàn)了,這意味著java1-java7中凌埂,實(shí)現(xiàn)了Collection接口的全部類都需要實(shí)現(xiàn)stream方法驱显,否則,那些類將無(wú)法在java8里面通過(guò)編譯瞳抓。java為了保持向下兼容性埃疫,java8引入了默認(rèn)方法,用關(guān)鍵字default表示挨下。形象化說(shuō)法就是:Collection告訴他的子類熔恢,如果你沒(méi)有實(shí)現(xiàn)stream方法,就用我的吧臭笆。

stream方法

我們可以看到叙淌,在j8中秤掌,很多地方都使用了默認(rèn)方法,如Iterable接口中的forEachspliterator鹰霍。

子接口中或者實(shí)現(xiàn)類中實(shí)現(xiàn)覆蓋默認(rèn)方法闻鉴,需要Override注解。

看一下默認(rèn)方法在復(fù)雜的繼承關(guān)系中的一種特殊情況:


image.png

如圖茂洒,OverrideChild既實(shí)現(xiàn)了Parent接口孟岛,又繼承了實(shí)現(xiàn)了Parent接口的類,那么調(diào)用時(shí)督勺,應(yīng)該調(diào)用哪個(gè)方法呢渠羞?此例子打印出來(lái)的是from ParentImpl,原因在于,與接口中定義的默認(rèn)方法相比智哀,類中重寫(xiě)的方法更具體次询。

調(diào)用優(yōu)先級(jí)為:類重寫(xiě)方法>子接口重寫(xiě)方法>父接口方法

接口允許多繼承,因此瓷叫,有了默認(rèn)方法屯吊,子類就可以繼承多個(gè)接口中的默認(rèn)實(shí)現(xiàn)。這在某種形式上實(shí)現(xiàn)了多重繼承的功能摹菠。(注意:如果在繼承的多個(gè)接口中盒卸,有多個(gè)簽名相同的默認(rèn)方法,編譯器將報(bào)錯(cuò))

  • 接口的靜態(tài)方法

在以往的jdk版本中次氨,接口是不允許存在靜態(tài)方法的蔽介,j8發(fā)布后,為了使Stream.of靜態(tài)方法糟需,加入了靜態(tài)方法屉佳,使得同一接口的子類可以共享這一靜態(tài)方法谷朝。

try-with-resources

AS3.0在所有android api層面對(duì)try-with-resources進(jìn)行支持洲押。

try-with-resources聲明一個(gè)或多個(gè)資源的 try 語(yǔ)句。一個(gè)資源作為一個(gè)對(duì)象圆凰,必須在程序結(jié)束之后隨之關(guān)閉杈帐。 try-with-resources語(yǔ)句確保在語(yǔ)句的最后每個(gè)資源都被關(guān)閉 。

任何實(shí)現(xiàn)了 java.lang.AutoCloseable的對(duì)象, 包括所有實(shí)現(xiàn)了 java.io.Closeable 的對(duì)象, 都可以用作一個(gè)資源专钉。

先來(lái)一段代碼:

image.png

可以看到挑童, try-with-resources 語(yǔ)句聲明的資源是一個(gè) BufferedReader。聲明語(yǔ)句在緊跟在 try 關(guān)鍵字的括號(hào)里面跃须。在j8之前站叼,如果我要是有一個(gè)資源,在使用之后菇民,需要顯示的效用其close方法將其關(guān)閉尽楔,但j8新的語(yǔ)法糖出現(xiàn)后投储,我們只需要將其聲明在try中,在資源使用完畢之后阔馋,將自動(dòng)關(guān)閉玛荞,不需要手動(dòng)調(diào)用。上面的語(yǔ)句相當(dāng)于:

image.png

我們可以在try后聲明多個(gè)資源呕寝,見(jiàn)下圖:

image.png

我們也可以在try-with-resources 語(yǔ)句后添加自己需要捕獲的異逞校或添加finally語(yǔ)句塊,如下圖:

image.png

注意下梢,在try-with-resources 語(yǔ)句中, 任意的 catch 或者 finally 塊都是在聲明的資源被關(guān)閉以后才運(yùn)行客蹋。

如果try-with-resources語(yǔ)句中資源的Close方法和try代碼塊中都拋出了異常,Close 方法拋出的異常被抑制孽江,try代碼塊中的異常會(huì)被拋出嚼酝。
Java7之后,可以使用Throwable.getSuppressed方法獲得被抑制的異常竟坛。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末闽巩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子担汤,更是在濱河造成了極大的恐慌涎跨,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件崭歧,死亡現(xiàn)場(chǎng)離奇詭異隅很,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)率碾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門叔营,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人所宰,你說(shuō)我怎么就攤上這事绒尊。” “怎么了仔粥?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵婴谱,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我躯泰,道長(zhǎng)谭羔,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任麦向,我火速辦了婚禮瘟裸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诵竭。我一直安慰自己话告,他們只是感情好十办,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著超棺,像睡著了一般向族。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上棠绘,一...
    開(kāi)封第一講書(shū)人閱讀 50,050評(píng)論 1 291
  • 那天件相,我揣著相機(jī)與錄音,去河邊找鬼氧苍。 笑死夜矗,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的让虐。 我是一名探鬼主播紊撕,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼赡突!你這毒婦竟也來(lái)了对扶?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤惭缰,失蹤者是張志新(化名)和其女友劉穎浪南,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體漱受,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡络凿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了昂羡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片絮记。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖虐先,靈堂內(nèi)的尸體忽然破棺而出怨愤,到底是詐尸還是另有隱情,我是刑警寧澤赴穗,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布憔四,位于F島的核電站,受9級(jí)特大地震影響般眉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜潜支,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一甸赃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧冗酿,春花似錦埠对、人聲如沸络断。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)貌笨。三九已至,卻和暖如春襟沮,著一層夾襖步出監(jiān)牢的瞬間锥惋,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工开伏, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留膀跌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓固灵,卻偏偏與公主長(zhǎng)得像捅伤,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子巫玻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容