In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article will explain in detail what are the methods of studying and learning Kotlin, and the content of the article is of high quality, so the editor will share it with you for reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.
Kotlin is a very comfortable language. Compared with Java, it is more concise, saves trivial grammar work, and provides features like Lambda,String template,Null Safe Operator. Make it easy for developers to use.
The average Java/Android programmer usually takes a very short time to use Kotlin quickly. Combining the many advantages of Kotlin, coupled with the fact that the Flipboard US team has introduced Kotlin,Flipboard since 2015, the China team has also begun to adopt Kotlin as the main development language of Android.
Although Kotlin is simple and quick to use, because of its own habit of in-depth research, every time I come into contact with the new features of Kotlin, I study its essence non-stop. Here are some methods about how to study Kotlin to quickly study and master Kotlin.
What exactly are you studying?
For example, Kotlin provides a type called Object, with which we can quickly implement singleton pattern applications. The code is very simple.
Object AppSettings {}
So the question is, how to implement the object class of kotlin, the implementation principle of the Null security operator, whether the Lambda expression is based on the inner class or the real Lambda, these are the objects we want to study.
How to study
Both Kotlin and Java run on JVM, but JVM doesn't really know Java and Kotlin because it only works with bytecode (that is, class files).
Therefore, by studying bytecode, we can understand some in-depth principles of Kotlin.
Because the same bytecode is decompiled into java and kotlin files is equivalent, so decompiling kotlin compiled class files into Java is also of reference and research value.
What are the practical methods
Using the Kotlin plug-in
Using tools such as kotlinc,javap
Some practice
Principle of Null Safe Operator implementation
In Java, we often encounter the problem of null pointer. Kotlin specially adds a null pointer security operator. It is used as follows
Fun testNullSafeOperator (string: String?) {System.out.println (string?.toCharArray ()? .getOrNull (10)? hashCode ())}
When we make a call like this
TestNullSafeOperator (null) testNullSafeOperator ("12345678901") testNullSafeOperator ("123")
The resulting output is
Null 49 null
As you can see from the result, instead of throwing a NullPointerException like Java, it does not continue when it encounters a null pointer.
So how does the null pointer security operator of Kotlin work? we can use IntelliJ IDE's Kotlin plug-in to assist us in our research. The steps are as follows
Use IntelliJ IDE to open a Kotlin file to be studied (make sure the Kotlin plug-in is installed)
Click to Show Kotlin Bytecode according to the following figure
After the above steps, you will get a bytecode like this
/ / access flags 0x19 public final static testNullSafeOperator (Ljava/lang/String;) V @ Lorg/jetbrains/annotations/Nullable; () / / invisible, parameter 0 L0 LINENUMBER 11 L0 GETSTATIC java/lang/System.out: Ljava/io/PrintStream; ALOAD 0 DUP IFNULL L1 / / A pair of string strings determines null INVOKESTATIC kotlin/text/StringsKt.toCharArray (Ljava/lang/String ) [C DUP IFNULL L1 / / one pair of CharArray decides empty BIPUSH 10 INVOKESTATIC kotlin/collections/ArraysKt.getOrNull ([CI) Ljava/lang/Character; DUP IFNULL L1 / / one pair of Char decides empty INVOKEVIRTUAL java/lang/Object.hashCode () I INVOKESTATIC java/lang/Integer.valueOf (I) Ljava/lang/Integer; GOTO L2 L1 POP ACONST_NULL L2 INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object) ) V L3 LINENUMBER 12 L3 RETURN L4 LOCALVARIABLE string Ljava/lang/String; L0 L4 0 MAXSTACK = 3 MAXLOCALS = 1}
As can be seen from bytecode analysis, in fact, the so-called null pointer security operator is used internally to ensure that null pointers do not appear. If the bytecode is difficult to understand, then we use the Decompile function above to convert bytecode to Java, as shown in the figure.
The decompiled Java code is
Public static final void testNullSafeOperator (@ Nullable String string) {PrintStream var10000; Integer var5; label18: {var10000 = System.out; if (string! = null) {PrintStream var2 = var10000; if (string = = null) {throw new TypeCastException ("null cannot be cast to non-null type java.lang.String") } char [] var4 = ((String) string) .toCharArray (); Intrinsics.checkExpressionValueIsNotNull (var4, "(this as java.lang.String) .toCharArray ()"); char [] var3 = var4; var10000 = var2; if (var3! = null) {Character var10001 = ArraysKt.getOrNull (var3, 10) If (var10001! = null) {var5 = Integer.valueOf (var10001.hashCode ()); break label18;} var5 = null;} var10000.println (var5);}
Isn't it easier to read it this way?
Research on Object types
Let's go back to the Object type, or give another example to see how to use the
/ / this is the definition of object AppSettings {fun updateConfig () {/ / do some updating work}}
The application is also very simple.
/ / call AppSettings.updateConfig () in Kotlin file / / call AppSettings.INSTANCE.updateConfig () in Java file
Let's take a look at AppSettings's bytecode file first.
/ / = AppSettings.class = / / class version 50.0 (50) / / access flags 0x31 public final class AppSettings {/ / access flags 0x11 public final updateConfig () V L0 LINENUMBER 7 L0 RETURN L1 LOCALVARIABLE this LAppSettings; L0 L1 0 MAXSTACK = 0 MAXLOCALS = 1 / / access flags 0x2 private () V L0 LINENUMBER 4 L0 ALOAD 0 INVOKESPECIAL java/lang/Object. () V ALOAD 0 CHECKCAST AppSettings PUTSTATIC AppSettings.INSTANCE: LAppSettings; RETURN L1 LOCALVARIABLE this LAppSettings; L0 L1 MAXSTACK = 1 MAXLOCALS = 1 / / access flags 0x19 public final static LAppSettings; INSTANCE / / access flags 0x8 static () V L0 LINENUMBER 4 L0 / / static code block, that is, NEW AppSettings INVOKESPECIAL AppSettings is instantiated when the class is loaded. () V RETURN MAXSTACK = 1 MAXLOCALS = 0 @ Lkotlin/Metadata (mv= {1,1,5}, bv= {1,0,1}, ku001, D1 = {"\ u0000\ u0012\ n\ u0018\ u0002\ n\ u0002\ u0010\ u00000\ n\ u0002\ u0008\ u0002\ n\ u0002\ n\ u00000\ u0008\ u00c6\ u0002\ u0018\ u00002\ u00020\ u0001B\ u0007\ u0008\ u0002\ u00a2\ u0002\ u0010\ u0002J\ u0006\ u0010\ u0001a\ u00020\ u0006\ u0002} 2d2 = LAppSettings {u0002 ",", "() V", "updateConfig", "", "production sources for module KotlinObject"}) / / compiled from: AppSettings.kt}
Thus, Kotlin's object, which is the implementation of Java's singleton pattern, initializes the instance in a static code block. If you don't understand the bytecode, try decompiling it into Java code to study it in detail.
Research on Lambda expression
In addition, Kotlin also supports Lambda expressions. Since not all versions of JVM support invokedynamic (the bytecode instruction on which Lambda expressions depend), such as Java 6's JVM, this includes many Android devices. So we suspect that Kotlin may have converted lambda expressions into anonymous inner classes like Scala.
A simple example of Lambda expression
Class Test {fun testObservable () {val observable = Observable () observable.addObserver {o, arg-> System.out.println ("$o $arg")}
We also use plug-ins to view bytecode
/ / = Test.class = / / class version 50.0 (50) / / access flags 0x31 public final class Test {/ / access flags 0x11 public final testObservable () V L0 LINENUMBER 8 L0 NEW java/util/Observable DUP INVOKESPECIAL java/util/Observable. () V ASTORE 1 L1 LINENUMBER 9 L1 ALOAD 1 GETSTATIC Test$testObservable$1.INSTANCE: LTest$testObservable$1; / / this is the use of anonymous inner classes (often containing the $character) CHECKCAST java/util/Observer INVOKEVIRTUAL java/util/Observable.addObserver (Ljava/util/Observer;) V L2 LINENUMBER 12 L2 RETURN L3 LOCALVARIABLE observable Ljava/util/Observable; L1 L3 LOCALVARIABLE this LTest L0 L3 0 MAXSTACK = 2 MAXLOCALS = 2 / / access flags 0x1 public () V L0 LINENUMBER 6 L0 ALOAD 0 INVOKESPECIAL java/lang/Object. () V RETURN L1 LOCALVARIABLE this LTest; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 1 @ Lkotlin/Metadata (mv= {1,1,5}, bv= {1,0,1}, ku001, D1 = {"\ u0000\ u0012\ n\ u0002\ u0018\ u0002\ n\ u0002\ u0010\ u00000\ n\ u0008\ u0002\ n\ u0002\ u0002\ n\ u0018\ u002\ u00020\ u0001B\ u0005\ u00a2\ u0006\ u0002\ u0010\ u0006\ u0006\ u0010\ u00020\ u0004\ u00a8\ u0005"}, 2d2 = {LTest ",", "() V", "testObservable", "", "production sources for module KotlinObject"}) / / access flags 0x18 final static INNERCLASS Test$testObservable$1 null null / / compiled from: Space.kt} / / = Test$testObservable$1.class = / / class version 50.0 (50) / / access flags 0x30 / / generated anonymous inner class The rule is the current class name $current method name $anonymous internal class serial number final class Test$testObservable$1 implements java/util/Observer {/ / access flags 0x11 public final update (Ljava/util/Observable) Ljava/lang/Object;) V L0 LINENUMBER 10 L0 GETSTATIC java/lang/System.out: Ljava/io/PrintStream; NEW java/lang/StringBuilder DUP INVOKESPECIAL java/lang/StringBuilder. V ALOAD 1 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/Object;) Ljava/lang/StringBuilder; LDC "" INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;) Ljava/lang/StringBuilder; ALOAD 2 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/Object;) Ljava/lang/StringBuilder; INVOKEVIRTUAL java/lang/StringBuilder.toString () Ljava/lang/String; INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String ) V L1 LINENUMBER 11 L1 RETURN L2 LOCALVARIABLE this LTest$testObservable$1; L0 L20 LOCALVARIABLE o Ljava/util/Observable; L0 L21 LOCALVARIABLE arg Ljava/lang/Object; L0 L22 MAXSTACK = 3 MAXLOCALS = 3 / / access flags 0x0 () V ALOAD 0 INVOKESPECIAL java/lang/Object. () V RETURN MAXSTACK = 1 MAXLOCALS = 1 / / access flags 0x19 public final static LTest$testObservable$1; INSTANCE / / access flags 0x8 static () V NEW Test$testObservable$1 DUP INVOKESPECIAL Test$testObservable$1. () V PUTSTATIC Test$testObservable$1.INSTANCE: LTest$testObservable$1; RETURN MAXSTACK = 2 MAXLOCALS = 0 @ Lkotlin/Metadata (mv= {1,1,5}, bv= {1,0,1}, Kend3 D1 = {"\ u0000\ u0016\ n\ u0000\ n\ u0002\ u0010\ u0002\ n\ u0002\ u0018\ u0002\ n\ u0002\ u008\ u0002\ n\ u0002\ u0010\ u0016\ n\ u00012\ u0010\ u0010\ u001a\ u00020\ u00012\ u0010\ u0010\ u001a\ n\ u0004*\ u0004\ u0018\ u00030\ u00030\ u00032\ u000e\ u0010\ u0005\ u001a\ n\ u00060\ 6000H\ u00a2\ 0006\ 000u8\ u0007," 2d4 = "{u00030\ u00030\ u00032\ u0003\ u0010\ u0005\ u001a\ n\ u00060\ 6000H\ u0006\ 000u2\ 0008" "o", "Ljava/util/Observable "," kotlin.jvm.PlatformType "," arg ","," update "}) OUTERCLASS Test testObservable () V / / access flags 0x18 final static INNERCLASS Test$testObservable$1 null null / / compiled from: Space.kt}
Analyzing the bytecode shows that there are two class files, so it can be inferred that the Lambda expression of Kotlin is currently a syntax sugar implementation based on inner classes.
In addition, we can also use kotlinc (Kotlin compiler to verify)
Kotlinc Test.kt
When the execution is complete, view the generated class file
Ls | grep ^ Test Test$testObservable$1.class Test.class Test.kt
Of course, we can also use javap to do the same for viewing bytecode, that is, javap-c className.
In addition, we can also use the above method to study the characteristics of the following Kotlin
Lazy initialization
When expression
Method reference
On the study of learning Kotlin methods to share here, I hope that the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.