1. Why use Kotlin for Android?

Since The acquisition of Java by Oracle, Google has often been sued by Oracle for copyright, so Google chose Kotlin as the first language for Android development. According to the Android website, Kotlin is free and open, a static programming language developed by a particularly talented company called JetBrains. AndroidStudio is also based on his IDEA, Google also contributed to the advantages of open-source Kotlin:

  • Expressive and extremely concise

Kotlin’s modern language capabilities let you focus on expressing your ideas and write less boilerplate code.

  • More secure code

Kotlin helps you avoid NullPointerExceptions with @Nullable and @nonNULL contained in its type system. Android apps that use Kotlin are 20% less likely to crash.

  • interoperable

Can interwork with Java code and call each other

  • Structured concurrency

Kotlin coroutines simplify asynchronous programming, allowing you to perform common tasks such as network calls and database updates easily and efficiently.

2. Basic grammar

2.1, variables,

Type inference Is derived according to the type of initialization for type variable variable val var immutable variables definition is equivalent to the final of the Java modified Kotlin is a static language, compile time decided to things

class VariableDemo {
 // var < identifier > : < type > = < initialization value >
 // val < identifier > : < type > = < initialization value >
 // var userName:String=" "
    var name="Aimes"// Automatically deduce to string
    val age=100// Automatically derive to Int
}
Copy the code

Code decompiledJava (a plug-in that converts Kotlin into bytecode and decompiles it into a Java file)

public final class VariableDemo {
   @NotNull
   private String name = "Aimes";
   private final int age = 100;

   @NotNull
   public final String getName(a) {
      return this.name;
   }

   public final void setName(@NotNull String var1) {
      Intrinsics.checkParameterIsNotNull(var1, "
      
       "
      ?>);
      this.name = var1;
   }

   public final int getAge(a) {
      return this.age; }}Copy the code

Var can be read and written; val can be read and written; val can be read and not written

2.2, functions,

The method void==Unit that does not return a value can be omitted

  fun testFun(number1:Int,number2:Int):Unit{
        println(number1+number2)
    }
Copy the code

A method with a return value and an argument

    fun testFun(number1:Int,number2:Int):Int{
        println(number1+number2)
        return number1+number2
    }
Copy the code

A more advanced way to write this = derive the return value type

fun add(number1: Int,number2: Int) = number1+number2 // The return value is derived as Int
fun add3(number1: Int, number2: Int) = "Aimes"// The return value is derived as String
Copy the code

In Java, you can have variable arguments. In Kotlin, you need to use the vararg keyword to modify variable arguments.

 fun lenMethod(vararg number:Int){
     println(number.size)
 }
Copy the code

Lambda expression functions (here’s an example, I’ll write a post about lambda later)

fun main(a){
    // Lambda expression function
    val addMethod : (Int.Int) - >Int = {number1, number2 -> number1 + number2}
    val r= addMethod(9.9)
    println(r)
}
Copy the code

2.3 string template

It’ll be a little faster

  val name = "Aimes"
  val age = 28
  val sex = 'M'
  val info = "ABCDEFG"
  println("name:$name,  age:$age,  sex:$sex  info:$info")
Copy the code

Three double quotes, output as is, no escaping characters for newlines,

    val infoMesage = """ AAAAAAAAAAA"aaa" BBBBBBBBBBB CCCCCCCCCCC DDDDDDDDDDD EEEEEEEEEEE """  // Front space
    println(infoMesage)// The output will have a leading space
     val infoMesage2 = """ AAAAAAAAAAA BBBBBBBBBBB CCCCCCCCCCC DDDDDDDDDDD EEEEEEEEEEE """.trimIndent()  / / no Spaces
Copy the code

TrimIndent () removes the front space and displays 999.99999.99999.99999.99999.99 {‘ $’}999

val price = "" "The ${'$'}99999.99 "" ".trimIndent()
    println(price)
Copy the code

2.4. Null check is one of Kotlin’s features

varname:String? =null/ /? A notification is sent telling all callers that the variable can now be null and that you, the callers, can take the action yourself
fun main(a) {
    // If you do not fix the error, the compiler will report the error as shown in the following figure
}
Copy the code

There are three ways to fix this. The first way is to allow a null value to be returned in a method, and then add one after the return value, right? This leaves the remedy in the hands of the caller of the return value

fun main(a) {
    var testStr=test()
    //testStr.length
}
fun test(a):String? {return null
}
Copy the code

The error in teststr. length is the same as the error in teststr. length. Teststr.length is not allowed to return null. Teststr.length is not allowed to return null. Second remedy: When calling this property, add a dot in front of it. If this property is null, then the following code will not execute

fun main(a) {
    vartestStr=test() testStr? .length// If testStr is null,. Length is not executed
}
fun test(a):String? {return null
}
Copy the code

The third remedy is invoked by adding two to the front of the dot!! This attribute must not be null

fun main(a) {
    vartestStr=test() testStr!! .length// If testStr is null,. Length is not executed
}
fun test(a):String? {return null
}
Copy the code

The third remedy must be used with caution, if the attribute is 100% non-null, otherwise a null pointer exception will occur

2.5, interval

fun sectionTest(a){
    / / range.. You can only count from small to large
    for (index in 1.10.){
        print(index)
    }
    println("")
    // The interval down to can only be from large numbers to decimal numbers
    for (index in 10 downTo 1){
        print(index)
    }
    println("")
    / / step stride
    for (index in 1.10. step 4){
        print(index)
    }
    // In and downTo are closed interval unitl half closed and half open interval
    // Half-closed and half-open intervals can only be from small numbers to large numbers
    for(index in 1 until 10){
        print(index)
    }
}
Copy the code

Output results:

3. Compare and array

Equals equals (), but the yellow wavy line === compares the address of the object


    val name1: String = "Aimes"
    val name2: String = "Aimes"

    // -- compare the value itself
    // == equals to Java
    println(name1.equals(name2))
    println(name1 == name2)


    // -- Compare object addresses
    val test1:Int? =  10000
    val test2:Int? =  10000
    println(test1 === test2) // false
Copy the code

ArrayOf generic type derivation

 val numbers = arrayOf(1.2.3.4.5.6.7.8)
 / / value Numbers [index]
 numbers[0]
 2 / / way
  val numbers2 = Array<String>(10,  {value: Int- > ("aaa")})// val numbers2 = Array<String>
 						(10.// Array size
 						  {value: Int // Array subscript -
 						  > ("aaa")// assign aaa to value})
Copy the code

Or you could write it this way

 val numbers2 = Array<String>(10,  {value: Int -> if(value==5) ("666") else ("aaa")})for (value in numbers2) {
        println(value)
    }
Copy the code

Code after decompiledJava

public static final void main(a) {
      byte var1 = 10;
      String[] var2 = new String[var1];

      boolean var5;
      for(int var3 = 0; var3 < var1; ++var3) {
         var5 = false;
         String var8 = var3 == 5 ? "666" : "aaa";
         var2[var3] = var8;
      }

      String[] var11 = var2;
      int var4 = var2.length;

      for(int var10 = 0; var10 < var4; ++var10) {
         String value = var11[var10];
         var5 = false; System.out.println(value); }}Copy the code

4. Condition control

Expression ratio size

    val age=5;
    val age1=10;
    val maxValue=if (age>age1) age else age1
Copy the code

Interval judgment

val age=5;
 if(age in 1.18.){
        println("Underage")}else{
        println("Come of age")}Copy the code

When is the upgraded version of switch

val age=5;
 when(age){
        in 1.18.- > {// Determine whether it is between 1 and 18
            
        }
        19.21.22.24- > {// If one of them is satisfied, the branch is executed
            
        }
        else- > {// Do not satisfy the above conditions to take the branch}}Copy the code

Type derivation for when

var str= when(age){
        in 1.18.- > {"Age is$ageMinor"
        }
        19.21.22.24- > {"Age is$ageCome of age."
        }
        else- > {"Age is$ageAnd the other"
        }
    }
    println(str)
Copy the code

If the return type of each branch is different, STR is derived to Any, which is the Java equivalent of Object

5. Loops and labels

Any expression in Kotlin can be marked with a tag. The format of the tag is the identifier + @ symbol. For example, aaa@ and bottom@ are valid tags. To add a tag to an expression, you only need to add a tag before it. The break tag is applied

 tttt@ for (i in 1.20.) {

        for (j in 1.20.) {
            println("i:$i, j:$j")
            if (i == 5) {
                // break // j loop to break
                break@tttt // I loop to break}}Copy the code

return

fun testLabel(a){
    var numbers= arrayOf(1.2.3.4.5.6)
    testFor@numbers.forEach {
        when(it){
            5- > {// return // do not print aaa
               return@forEach/ / print aaa
            }
        }
    }
    println("aaa")}Copy the code

this

class SafeDemo {
    val name="Aimes"
    inner class SafeDemoInner{
        val name="Inner Love"
        fun test(a){
            println(this.name)/ / inner code and love
            println(this@SafeDemo.name)//}}}Copy the code

The for loop

 var items  = listOf<String>("Bill"."Zhang"."Fifty")
    for (item in items) {
        println(item)
    }

    items.forEach {
        println(it)
    }

    for (index in items.indices) {
        println("Subscription:$index, the corresponding value:${items[index]}")}Copy the code

6. Classes and Objects

Let’s start with an empty class

// The default is public, so you don't need to write public
class Test {}Copy the code

6.1. Construction methods

class Test(val age:Int) {// How to write the main structure
    constructor() :this(5)// The secondary construct must call the primary construct
    constructor(name:String):this(5)/ / structure
}
// The new keyword is not required
fun main(a) {
    Test(0)}Copy the code

In Java, class is final, so it can’t be inherited, but if I want to write a parent class, what if I use open in front of class, so it can be inherited, so I drop the final keyword

open class Test(val age:Int) {// How to write the main structure
constructor() :this(5)// The secondary construct must call the primary construct
    constructor(name:String):this(5)/ / structure

}
Copy the code

6.2 Default values for properties

In Java, you can have a default value for all property values, which is null, which is fine, but in Kotlini, if you don’t assign a value to a property, you get an error

  • ? Allow yourself to remedy the void
  • Give yourself an initial value and everybody’s happy
  • Fixed with lazy loading lateinit
  	val number=0;
    varid:String ? =null
    lateinit  var url:String// The null pointer will be null if it is used for lazy loading
Copy the code

6.3 Abstract Classes and Interfaces

Abstract classes and interfaces are written in a similar way to Java

interface ICallBack {
    fun onCallBack(a)
}
abstract class TestAbstract {
    abstract fun initView(a)
}
// Use both inheriting and implementing interfaces: then separate them with commas. When inheriting an abstract class or an open-decorated class, declare the main construct
 class TestInterface: TestAbstract(),ICallBack{
     override fun initView(a) {
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
     }

     override fun onCallBack(a) {
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.}}Copy the code

6.4 data Beans

Kotlin uses dataclass instead of Javabeans and generates copy function

data class UserBean(val userName:String,val password:String)

fun main(a) {
    var user=UserBean("aaa"."bbbb")
    var (username,password)=user.copy()
    var (_,amszlk)=user.copy()/ / want to copypassword
    println("username:$username,password:$password")
    println(amszlk)
}
Copy the code

Convert to Java code

public final class UserBean {
   @NotNull
   private final String userName;
   @NotNull
   private final String password;

   @NotNull
   public final String getUserName(a) {
      return this.userName;
   }

   @NotNull
   public final String getPassword(a) {
      return this.password;
   }

   public UserBean(@NotNull String userName, @NotNull String password) {
      Intrinsics.checkParameterIsNotNull(userName, "userName");
      Intrinsics.checkParameterIsNotNull(password, "password");
      super(a);this.userName = userName;
      this.password = password;
   }

   @NotNull
   public final String component1(a) {
      return this.userName;
   }

   @NotNull
   public final String component2(a) {
      return this.password;
   }

   @NotNull
   public final UserBean copy(@NotNull String userName, @NotNull String password) {
      Intrinsics.checkParameterIsNotNull(userName, "userName");
      Intrinsics.checkParameterIsNotNull(password, "password");
      return new UserBean(userName, password);
   }

   // $FF: synthetic method
   public static UserBean copy$default(UserBean var0, String var1, String var2, int var3, Object var4) {
      if ((var3 & 1) != 0) {
         var1 = var0.userName;
      }

      if ((var3 & 2) != 0) {
         var2 = var0.password;
      }

      return var0.copy(var1, var2);
   }

   @NotNull
   public String toString(a) {
      return "UserBean(userName=" + this.userName + ", password=" + this.password + ")";
   }

   public int hashCode(a) {
      String var10000 = this.userName;
      intvar1 = (var10000 ! =null ? var10000.hashCode() : 0) * 31;
      String var10001 = this.password;
      returnvar1 + (var10001 ! =null ? var10001.hashCode() : 0);
   }

   public boolean equals(@Nullable Object var1) {
      if (this! = var1) {if (var1 instanceof UserBean) {
            UserBean var2 = (UserBean)var1;
            if (Intrinsics.areEqual(this.userName, var2.userName) && Intrinsics.areEqual(this.password, var2.password)) {
               return true; }}return false;
      } else {
         return true; }}}Copy the code

6.5 Kotlin’s Object and companion Object

Only one of Kotlin’s only patterns is the Object class

object ObjectTest {
    fun showToast(a){}}/ / call
fun main(a) {
    ObjectTest.showToast()
}
Copy the code

The code after conversion to Java

public final class ObjectTest {
   public static final ObjectTest INSTANCE;

   public final void showToast(a) {}private ObjectTest(a) {}static {
      ObjectTest var0 = newObjectTest(); INSTANCE = var0; }}Copy the code

Since we are living in the world, we are living in the world

class CompanionObjectTest {
    companion object{
        val name="Aimes"
        fun show(a){ 
        	name.length
        }
    }
}
/ / call
fun main(a) {
    CompanionObjectTest.show()
}
Copy the code

After turning Java

public final class CompanionObjectTest {
   @NotNull
   private static final String name = "Aimes";
   public static final CompanionObjectTest.Companion Companion = new CompanionObjectTest.Companion((DefaultConstructorMarker)null);

   @Metadata( mv = {1, 1, 15}, bv = {1, 0, 3}, k = 1, d1 = {"\u0000\u001a\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0003\n\u0002\u0010 \ u0002 \ n \ \ u0086 \ u0003 u0000 \ b \ u0018 \ u00002 \ u00020 \ u0001B \ u0007 \ \ b u0002 ¢\ u0006 \ u0002 \ u0010 \ u0002J \ u0006 \ u0010 \ u0007 \ u001a \ U00020 \ bR \ u0014 \ u0010 \ u0003 \ u001a \ u00020 \ u0004X \ u0086D ¢\ u0006 \ b \ n \ u0000 \ u001a \ u0004 \ b \ u0005 \ u0010 \ u0006 ¨ \ u0006 \ t "}, d2 = {"Lsimple01/CompanionObjectTest$Companion;" , "", "()V", "name", "", "getName", "()Ljava/lang/String;" , "show", "", "kotlindemo"} )
   public static final class Companion {
      @NotNull
      public final String getName(a) {
         return CompanionObjectTest.name;
      }

      public final void show(a) {
        ((CompanionObjectTest.Companion)this).getName().length();
      }

      private Companion(a) {}// $FF: synthetic method
      public Companion(DefaultConstructorMarker $constructor_marker) {
         this(a); }}}/ / call
  public static final void main(a) {
      CompanionObjectTest.Companion.show();
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }
Copy the code

A Companion object is an object that is born with it, and when the class is initialized, the Companion object Companion is instantiated, and the Companion object’s properties become static variables of the class. When a method is called, the class calls the Companion Companion property Companion directly, and then calls the show method

Kotlin’s inner class

class Test {

    val I = "AAAA"

    // This is not an inner class. All members of the outer class cannot be retrieved
    // Nested class = You can write another class inside the class, but it is not an inner class
    class Sub {
        fun show(a) {
            println()
        }
        class A {

            class B {


                class C {}}}}// This is the inner class
    inner class Sub2 {

        fun show(a) {
            println(I)
        }

    }

}
Copy the code