Recently, Google released AS 3.0 and a series of support packages. There are many interesting new things. Because I have been looking at the support for Kotlin, I specifically looked up the support for Java8. The result is... Support for Java 8 I have talked about Kotlin-related stuff a long time ago, so I won't go into details here. One of the bright features in AS3 is support for Java8. First of all, let me talk about why we couldn't use the new features of Java8 before. The main reason is lambda syntax. In JVM, Java8 syntax is implemented through a bytecode operation command called invokedynamic, but this thing does not exist in Dalvik, so it has not been used. The reason why AS3.0 can be used now is that a desugar thing has been added to the new Android Studio. It is similar to invokedynamic on JVM, which translates Java8 bytecode into dalvik-recognizable one. Official website introduction: 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 and convert the internal lambda-related syntax into syntax that can be recognized by dalvik. This is too abstract, let's look at the code for details.
After a Java8 lambda syntax code like this is compiled and decompiled, you can see that it becomes like this:
We can see in the code above that in the compiled run() method there is a sentence 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, reducing one method call and directly becoming the body of the run method (equivalent to inlining). For the specific principle operation, please refer to the visitInvokeDynamicInsn method in the source code: GoogleCode, please bring your own ladder The above code demonstrates the operation of a pure function (see wiki for what is a pure function). Now let's look at an impure function. Before compilation:
After compilation:
The original lambda static object is no longer static; the lambda class constructor has an additional reference to the outer class object. Therefore, if the lambda body is not a non-pure function, it may cause a memory leak (the reason is the same as the inner class holding the outer class object). Method references This is really a joke. The official website says that Method References are fully supported. I originally thought that Kotlin's high-order functions would have performance issues, and I wanted to see if Java8 would have this problem. But after using it, I found it full of flaws. Whether it's Supplier or Predicate, all method calls of Function require a minimum API of 24. Damn, they are generally compatible with 14 now, so how can I use high-order methods? But I also tried to write one without considering the lower version and saw the effect. First is the code before Java8 compilation:
After Java8 compilation, it seems that the solution is the same, only the lambda part is replaced, and the method is still a normal object method call:
Kotlin code before compilation:
Kotlin compiled code:
So, the implementation of Kotlin is still exactly the same as Java. First, a class is generated, lambda is converted into an object, and then the invoke() method of the object is called. But don't forget that Kotlin has a magical inline keyword, which is specifically used to solve the problem of generating a lot of objects inexplicably. Assuming that the inline keyword is added to the test() method above, the compiled code becomes like this, which is equivalent to not calling the test() method, so there is no extra Function0 object generated:
I wanted to praise J8 support because I thought it was done by converting the pure function of lambda body into static method and directly changing lambda into static method call, but it turned out to be worse than Kotlin. It feels like Google added a gimmick of Java8 support for KPI. |
<<: 5 Tips to Make Your Mobile User Experience Stand Out
Produced by: Science Popularization China Produce...
Money Making System Course Catalog Earning money ...
From 1999 to 2023, from Shenzhou-1 to Shenzhou-17...
Affected by the epidemic, many people now choose ...
When, where, and how did the key evolutionary lin...
After completing the basic steps of on-site optim...
As we have just entered 2016, the Chinese mainlan...
"As expected, House of Cards continued to be...
Generally speaking, there are two main purposes o...
He Shen's surname was not He, but Niu Hulu. T...
Where will marketing go in 2018? Consumption and ...
The 15th strategy of the three crazy demolishers ...
Every autumn and winter, you can always see a gia...
More than 111 years ago, on April 10, 1912, the w...
Information flow advertising often encounters var...