Android studio 3 supports Java 8. Do you dare to use it

Abstract: this morning, Google released as 3.0 and a series of support packages. There are a lot of interesting new things, because I've been looking at kotlin's support before. I specifically turned over the support methods for Java 8. The results

This article was originally created by the open source laboratory. For reprint, please indicate with a link: https://kymjs.com/code/2017/10/26/01/

Support Java 8

I've been talking about kotlin a long time ago, so I won't go into detail here. AS3 has a bright feature that supports J8. First, let's talk about why we couldn't use the new features of Java 8 before. The main reason is lambda syntax. In the JVM, the syntax of Java 8 is completed through a bytecode operation command called invokedynamic, but this is not available in Dalvik, so it has not been used.

The reason why AS3.0 can be used now is that a desugar is actually added to the new Android studio. It is similar to invokedynamic on the JVM, which translates the bytecode of Java 8 into Dalvik recognizable.

Introduction to the official website:

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.

What can desugar do

First look at the official picture:

After javac is executed, desugar will operate on the class to convert the internal lambda related syntax into the syntax recognized by Dalvik. It's too abstract. Let's look at the code.

After the code of java8 lambda syntax is compiled and decompiled, you can see that it becomes like this:

We can see the above code. In the compiled run () method, there is a mainactivity. Lambda $oncreate $0 $mainactivity(); In fact, this sentence is the original lambda body, which is converted into a static method in the mainactivity class. After the final compilation into DEX, it will be optimized again to reduce one method call and directly become the body of the run method (equivalent to inline). See the visitinvokedynamicinsn method of the source code for the specific principle and operation: Please bring your own ladder for Google Code

The above code demonstrates the operation of a pure function (what is a pure function wiki). Let's look at a non pure function. Before compilation:

After compilation:

The original lambda static object is no longer static; The construction method of lambda class has a reference to an external class object. Therefore, if lambda body is not a pure function, it may cause memory leakage (the reason is the same as that the internal class holds the external class object). Finally, an official introduction is attached: https://developer.android.com/studio/write/java8-support.html

Method reference

This really makes me laugh and cry. According to the official website, method references fully supports it. Originally, I thought that kotlin's high-order functions would have performance problems. I also wanted to see if Java 8 would have this problem. But I used it and the slot was full. No matter whether it is supplier or predicate, all method calls of function must be at least api24. Shit, now they are generally compatible with 14. How do you let me use high-level methods. However, I also tried to write one regardless of the lower version and see the effect.

The first is java 8 precompiled Code:

After java8 compilation, it seems that the soup does not change, only the lambda part is replaced, and the method is still called by ordinary object methods:

Kotlin precompiled Code:

Kotlin compiled code:

So kotlin is as like as two peas in Java, and first generates a class that transforms lambda into objects, and then calls the invoke () method of the object. But don't forget that kotlin has a magical inline keyword, which is specially used to solve the inexplicable situation of generating a large number of objects. Suppose that after adding the inline keyword to the above test () method, the compiled code becomes like this, which is equivalent to not calling the test () method, so there are no multi generated function0 objects:

Originally, I wanted to praise J8's support, because I initially thought it was to convert the pure functions of lambda body into static methods and directly change lambda into static method calls. However, I didn't expect it to be better than kotlin. It feels like Google added a gimmick supported by Java 8 for KPI.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>