成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Android Studio3支持Java8了,就問你敢用嗎

移動(dòng)開發(fā) Android
日前,Google 發(fā)布了 AS 3.0,以及一系列的 Support 包,有意思的新東西挺多,因?yàn)橹耙恢痹诳?kotlin的支持,特地翻了一下對 Java8 的支持方式,結(jié)果……

日前,Google 發(fā)布了 AS 3.0,以及一系列的 Support 包,有意思的新東西挺多,因?yàn)橹耙恢痹诳?kotlin的支持,特地翻了一下對 Java8 的支持方式,結(jié)果……

支持 Java 8

kotlin 相關(guān)的東西很早以前我就在講了,這里就不再細(xì)說了。AS3里面有一個(gè)亮眼的特性就是支持J8。首先說一下為什么以前我們不能用Java8的新特性,最主要的原因就是 lambda 語法。在 JVM 中,Java8 的語法是通過一個(gè)叫做 invokedynamic 的字節(jié)碼操作命令完成的,但是這東西在 dalvik 中并沒有,因此一直不能用。

現(xiàn)在AS3.0之所以能用,實(shí)際上是在新的Android Studio中加入了一個(gè) desugar 的東西,他就類似 JVM 上的 invokedynamic ,把Java8的字節(jié)碼翻譯成 dalvik 可識(shí)別的。

官網(wǎng)介紹:

Android Studio provides built-in support for using certain Java 8 language features and third-party libraries that use them. As shown in figure 1, the default toolchain implements the new language features by performing bytecode transformations, called desugar, on the output of the javac compiler.

desugar 能干啥

首先看張官方圖:

Android Studio3支持Java8了,就問你敢用嗎

在 javac 執(zhí)行后,desugar 會(huì)對 class 做操作,將內(nèi)部的lambda相關(guān)的語法轉(zhuǎn)換為 dalvik 可識(shí)別的語法。

說的太抽象具體表現(xiàn)我們看代碼。

 

  1. @Override 
  2. protected void onCreate(Bundle savedInstanceState) { 
  3.     super.onCreate(savedInstanceState); 
  4.     setContentView(R.layout.activity_main); 
  5.  
  6.     new Thread(() -> { 
  7.         Log.d("kymjs""========"); 
  8.     }).start(); 

一個(gè)這樣的Java8 lambda語法的代碼被編譯以后,反編譯它,可以看到變成了這樣:

 

  1. protected void onCreate(Bundle savedInstanceState) { 
  2.     super.onCreate(savedInstanceState); 
  3.     this.setContentView(2131296283); 
  4.     (new Thread(MainActivity$$Lambda$0.$instance)).start(); 
  5.  
  6. // $FF: synthetic class 
  7. final class MainActivity$$Lambda$0 implements Runnable { 
  8.     static final Runnable $instance = new MainActivity$$Lambda$0(); 
  9.  
  10.     private MainActivity$$Lambda$0() { 
  11.     } 
  12.  
  13.     public void run() { 
  14.         MainActivity.lambda$onCreate$0$MainActivity(); 
  15.     } 

我們看到上面的代碼,在編譯后的 run() 方法內(nèi)有一句 MainActivity.lambda$onCreate$0$MainActivity(); 其實(shí)這一句就是原本lambda body,他被轉(zhuǎn)換成了 MainActivity 類中的一個(gè) static method。在最終編譯成 dex 后會(huì)再次優(yōu)化,減少一次方法調(diào)用直接變成run方法的body(相當(dāng)于內(nèi)聯(lián))。具體原理操作請見源碼的 visitInvokeDynamicInsn 方法: GoogleCode請自備梯子

上面的代碼演示了純函數(shù)(什么是純函數(shù)自己wiki)的操作,下面看一個(gè)非純函數(shù)的。

編譯前:

 

  1. public class MainActivity extends AppCompatActivity { 
  2.  
  3.     String mString = "hello"
  4.  
  5.     @Override 
  6.     protected void onCreate(Bundle savedInstanceState) { 
  7.         super.onCreate(savedInstanceState); 
  8.         setContentView(R.layout.activity_main); 
  9.  
  10.         new Thread(() -> { 
  11.             Log.d("kymjs""========" + mString); 
  12.         }).start(); 
  13.     } 

編譯后:

 

  1. protected void onCreate(Bundle savedInstanceState) { 
  2.     super.onCreate(savedInstanceState); 
  3.     this.setContentView(2131296283); 
  4.     (new Thread(new MainActivity$$Lambda$0(this))).start(); 
  5.  
  6. // $FF: synthetic class 
  7. final class MainActivity$$Lambda$0 implements Runnable { 
  8.     private final MainActivity arg$1; 
  9.  
  10.     MainActivity$$Lambda$0(MainActivity var1) { 
  11.         this.arg$1 = var1; 
  12.     } 
  13.  
  14.     public void run() { 
  15.         this.arg$1.lambda$onCreate$0$MainActivity(); 
  16.     } 

原本的 lambda 靜態(tài)對象不再是靜態(tài)的了;lambda 類的構(gòu)造方法多了一個(gè)外部類對象的引用。因此,如果 lambda body 不是一個(gè)非純函數(shù),是有可能會(huì)造成內(nèi)存泄漏的(原因跟內(nèi)部類持有外部類對象是一樣)。

方法引用

這個(gè)就實(shí)在是讓我哭笑不得了。官網(wǎng)標(biāo)注,Method References 完全支持了,原本想到kotlin 的高階函數(shù)會(huì)有性能問題,還想看看Java8會(huì)不會(huì)有這個(gè)問題。但是我用了一下,槽點(diǎn)滿滿。不管是 Supplier 還是 Predicate , Function 所有的方法調(diào)用都得要最低 API24,我靠現(xiàn)在普遍都是兼容到14的吧,你這讓我怎么用高階方法。不過我也嘗試不考慮低版本寫了一個(gè),看了一下效果。

首先是Java8編譯前代碼:

 

  1. public String str = "hello"
  2.  
  3. @Override 
  4. protected void onCreate(Bundle savedInstanceState) { 
  5.     super.onCreate(savedInstanceState); 
  6.     setContentView(R.layout.activity_main); 
  7.  
  8.     test(() -> str); 
  9.  
  10. public void test(Supplier<String> block) { 
  11.     System.out.println("=======" + block.get()); 

Java8編譯后,貌似換湯不換藥,只替換lambda部分,方法內(nèi)依舊是普通對象方法調(diào)用:

 

  1. protected void onCreate(Bundle savedInstanceState) { 
  2.     super.onCreate(savedInstanceState); 
  3.     this.setContentView(2131296283); 
  4.     this.test(new MainActivity$$Lambda$0(this)); 
  5.  
  6. public void test(Supplier<String> block) { 
  7.     System.out.println("==========" + (String)block.get()); 
  8.  
  9. // $FF: synthetic class 
  10. final class MainActivity$$Lambda$0 implements Supplier { 
  11.     private final MainActivity arg$1; 
  12.  
  13.     MainActivity$$Lambda$0(MainActivity var1) { 
  14.         this.arg$1 = var1; 
  15.     } 
  16.  
  17.     public Object get() { 
  18.         return this.arg$1.lambda$onCreate$0$MainActivity(); 
  19.     } 

kotlin編譯前代碼:

 

  1. val str: String = "hello" 
  2.  
  3. override fun onCreate(savedInstanceState: Bundle?) { 
  4.     super.onCreate(savedInstanceState) 
  5.     setContentView(R.layout.activity_main) 
  6.     test { 
  7.         str 
  8.     } 
  9.  
  10. fun test(block: () -> String) { 
  11.     println("=========${block.invoke()}"

kotlin編譯后的代碼:

 

  1. protected void onCreate(@Nullable Bundle savedInstanceState) { 
  2.     super.onCreate(savedInstanceState); 
  3.     setContentView((int) R.layout.activity_main); 
  4.     test(new MainActivity$onCreate$1(this)); 
  5.  
  6. public final void test(@NotNull Function0<String> block) { 
  7.     Intrinsics.checkParameterIsNotNull(block, "block"); 
  8.     System.out.println("=========" + ((String) block.invoke())); 
  9.  
  10. /* compiled from: MainActivity.kt */ 
  11. final class MainActivity$onCreate$1 extends Lambda implements Function0<String> { 
  12.     final /* synthetic */ MainActivity this$0; 
  13.  
  14.     MainActivity$onCreate$1(MainActivity mainActivity) { 
  15.         this.this$0 = mainActivity; 
  16.         super(0); 
  17.     } 
  18.  
  19.     @NotNull 
  20.     public final String invoke() { 
  21.         return this.this$0.getStr(); 
  22.     } 

所以說,kotlin在實(shí)現(xiàn)上跟Java也依舊是一模一樣,首先生成一個(gè)類,把lambda轉(zhuǎn)換成對象,再調(diào)用這個(gè)對象的 invoke() 方法。但是別忘了,kotlin有神奇的 inline 關(guān)鍵字,就專門用來解決這種莫名其妙的多生成一大堆對象的情況。

假設(shè)給上面的 test() 方法加上 inline 關(guān)鍵字后,編譯后的代碼就變成了這樣,相當(dāng)于并沒有調(diào)用test()方法,因此也就不存在多生成的 Function0 對象了:

 

  1. protected void onCreate(@Nullable Bundle savedInstanceState) { 
  2.     super.onCreate(savedInstanceState); 
  3.     setContentView((int) R.layout.activity_main); 
  4.     MainActivity this_$iv = this; 
  5.     System.out.println("=========" + this.str); 
  6.  
  7. public final void test(@NotNull Function0<String> block) { 
  8.     Intrinsics.checkParameterIsNotNull(block, "block"); 
  9.     System.out.println("=========" + ((String) block.invoke())); 

原本我是想夸一夸J8的支持,因?yàn)槲易畛跻詾樗菍?lambda body 的純函數(shù)轉(zhuǎn)換成靜態(tài)方法,直接將 lambda 改成靜態(tài)方法調(diào)用來做的,結(jié)果沒想到還不如 kotlin。感覺就是 Google 為了 KPI 去加了一個(gè) Java8 支持的噱頭。

責(zé)任編輯:未麗燕 來源: KymJS
相關(guān)推薦

2011-03-07 12:31:54

Filezilla

2010-05-13 14:08:58

Visual Stud

2012-05-16 09:27:53

Chrome瀏覽器

2012-06-21 09:37:50

Windows Pho存儲(chǔ)擴(kuò)充

2011-06-20 10:21:29

Chrome 13

2019-02-27 16:00:28

IT資產(chǎn)審計(jì)

2012-01-10 09:36:24

Windows 8ARM

2013-08-23 14:56:24

Windows 8.1

2009-04-02 08:57:23

IE8Firefox插件

2021-07-19 22:20:24

微軟Windows 11Windows

2010-01-27 09:17:43

Office 2010GUP加速

2012-03-02 11:37:43

Kubuntu社區(qū)項(xiàng)目

2012-09-19 10:57:02

vSphere 5.1VMwareVMware View

2015-07-20 13:24:42

Windows 10SD卡

2011-03-29 14:09:00

Windows Ser藍(lán)牙

2022-02-18 18:00:00

數(shù)字人人工智能冬奧黑科技

2010-08-19 09:37:35

IE6fixed

2012-12-14 13:31:02

2011-07-19 13:39:20

iOS HTML5

2011-10-11 11:17:24

UbuntuARM
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲综合一区二区三区 | 亚洲国产精品一区二区三区 | 精品亚洲一区二区三区 | 精品乱码一区二区三四区视频 | 亚洲97 | 欧美日韩中文字幕在线播放 | 国产视频在线观看一区二区三区 | 中文字幕精品视频 | 天天操综合网 | 国产一区二区三区 | 亚洲一区视频在线 | 一级片在线观看 | 久久久片 | av中文字幕在线观看 | 在线视频第一页 | 亚洲精品2| 中文字幕一区二区三区四区五区 | 神马久久av | 日韩精品免费一区二区在线观看 | 午夜av成人 | 国产成人精品综合 | 亚洲热在线视频 | 久久国内精品 | 99re66在线观看精品热 | 一色桃子av一区二区 | 国产精品大片 | 高清黄色毛片 | 欧美日韩激情 | 色婷婷影院 | 中文字幕成人av | 高清欧美性猛交 | 国产精品久久久久久52avav | 午夜成人免费视频 | 国产精品一区在线播放 | 国内精品久久影院 | 国产精品欧美一区二区三区 | 黄色av网站免费看 | 欧美一区免费 | 淫片一级国产 | 国产精品成人国产乱 | 亚洲二区在线 |