Java turns to Kotlin and points north

Keywords: Java Android kotlin

preface

  • Java is actually an interpretative language. Java source code is compiled to generate class files that can be executed by the JVM
  • The files generated by the Kotlin compiler can be recognized and executed by the JVM, so KT can still be executed in the same environment even if its syntax is very different from Java
  • Kotlin is a simplified and enhanced version of Java, and supports many high-level language features
  • Kotlin simplifies a lot of redundant syntax in Java. For example, there is no need to add after each statement in kotlin;

variable

statement

KT is very different from java declaration variables. KT has a type derivation mechanism, so you can not write types

//val, that is, value, represents a constant, corresponding to the variable with final in java
val a = 10
//var is variable, representing variable
var b = 10

//However, if you want to delay initialization, you need to add types, because you can't deduce at this time
val a:Int
var b:Int

Why var and val?

  • In Java, a variable is variable by default and immutable only after adding fianl. There is a risk that the variable will be changed (it should not have been changed). Adding fianl can avoid this risk, but because it is not mandatory, few programmers will take the initiative to add it
  • Using KT this form, we must pay attention to this problem, so as to avoid this risk
  • A good declaration habit is: a variable is first declared as val, and then it is changed to var

type

  • There are basic data types and their corresponding wrapper classes in Java. KT completely discards basic data types and is all objects
Java basic data typeKotlin object data typeexplain
intIntinteger
longLongLong integer
shortShortShort
floatFloatSingle precision floating point
doubleDoubleDouble precision floating point
booleanBooleanBoolean
charCharcharacter
byteByteByte type

function

  • Unlike Java, functions in KT need to be annotated with the fun keyword
  • Like Java, fill in parameters in parentheses, and leave only a pair of parentheses if there are no parameters. Unlike Java, the format of parameter declaration is "parameter name: parameter type"
  • The return value of the function is written after (), which is similar to the format of the parameter declaration: the return value type. If there is no return value, this part can be omitted directly
fun largerNumber(num1: Int, num2: Int): Int {
    return max(num1, num2)
}
//When there is only one line in the function, you can directly write =, return, or omit. Simplify ↓
fun largerNumber(num1: Int, num2: Int): Int = max(num1, num2)

//When using this syntax, the return value type can also be determined. The return value type can also be omitted and simplified
fun largerNumber(num1: Int, num2: Int) = max(num1, num2)

Parameter defaults

  • After setting the default value, this parameter is not mandatory
//Add the = sign after the parameter and write the value, which is the default value of the parameter
fun printParams(num: Int, str: String = "hello") {
    println("num is $num , str is $str")
}
  • What if the first parameter has a default value and you don't want to pass it in? KT supports the transfer of parameters from key value pairs, not necessarily in order
//Key value pairs are used to pass parameters to avoid the type mismatch of sequential parameters
printParams(str = "world", num = 123)

logical control

  • In Java, there are differences between expressions and statements. The former can assign values to variables, while the latter can't
  • However, in KT, the boundary between expression and statement is blurred. Many statements in KT will have return values and become an expression. It can be used for variable assignment

if statement

  • The last line of code for each condition of the if statement is returned as a return value
fun largerNumber(num1: Int, num2: Int): Int {
    val value = if (num1 > num2) {
        num1
    } else {
        num2
    }
    return value
}

//Use the grammar mentioned above to simplify ↓
fun largerNumber(num1: Int, num2: Int) = if (num1 > num2) num1 else num2

when statement

  • It can be understood as an enhanced version of the switch statement in Java:
    1. Built in break;
    2. Any type of parameter can be passed, even without parameters;
    3. Support type matching;
//Accurate matching
when (type) {
    "1" -> {
		1
	}
    "2" -> {
    	2
    }    
    //Only one line can omit braces
    "3" -> 3
    else -> {
    	//else is equivalent to the default of switch
		0
	}
}
//Type matching, is equivalent to Java instanceof
   when (num) {
   //Determine the type of num and print it
       is Int -> println("number is Int")
       is Double -> println("number is Double")
       else -> println("number not support")
   }


/*
Without parameter usage, write the judgment expression before - > completely
 Because it is a judgment expression, it is very flexible and can replace multiple ifelse
*/
when {
    type < 1 -> {
		"1"
	}
    type == 2 -> {
    	"2"
    }    
    type == 3 -> "3"
    else -> {
		0
	}
}

Circular statement

  • The for-i loop of java, that is, for(;;), was abandoned by KT
  • java's for each loop is greatly enhanced in KT and becomes a for in loop

For in loop and interval

  • In order to facilitate the use of the for in loop, KT has the syntax of generating a specific range - interval

Two end closed interval

//Mathematical representation [0,10]
val range = 0..10
 for (i in range) {
     println(i)
 }

Left closed right open section

//Mathematical representation [0,10)
val range = 0 until 10
  • It is often used to traverse an array. The right boundary is the length

Descending interval

//Print 10 to 1 in reverse order
 for (i in 10 downTo 1) {
     println(i)
 }

Rule skip some elements

//From 1 to 10 (excluding 10), add 2 for each cycle, which is equivalent to i = i + 2 in the for-i cycle
 for (i in 0 until 10 step 2) {
     println(i)
 }

repeat loop

  • Simple number of cycles
//Define number of cycles
var time = 3
repeat(time)
{ index ->
    println(index)
}

Classes and objects

instantiation

  • Simplify and remove the keyword new, because calling the constructor of a class must be to create its instance, and there is no need to use new to indicate it
//instantiation 
val p = Person()

inherit

  • KT class cannot inherit by default (equivalent to the class with final in Java). The reason is similar to variable declaration
  • You need to add the open keyword before the class to make the KT class inherit
//Define an inheritable Person class
open class Person {
	var name = ""
}

//KT uses: instead of extends as the inheritance keyword
class Student : Person() {
    var grade = 0
}

class constructor

primary constructor

  • The most commonly used constructor
  • characteristic:
    1. Each class can have only one primary constructor
    2. Class has a primary constructor without parameters by default
    3. You can add parameters
    4. No function body
//In the Student class, pass in name and grade as the parameters of the main constructor
class Student(val name: String, val grade: Int) : Person() {
}
  • The passed in parameter can be initialized directly, so it can be defined as val
  • If you want to execute logic in the main constructor, you can write in the init structure
class Student(val name: String, val grade: Int) : Person() {
    init {
    	//Print parameters at initialization
        println("name is " + name)
        println("grade is " + grade)
    }
}
  • It can be noted that there is a () after the parent class name in inheritance. In fact, this specifies which constructor of the parent class is called by the main constructor of the child class

Secondary constructor

  • Rarely used, because KT has the syntax of parameter default value, which can basically replace the secondary constructor
  • characteristic:
    1. A class can have multiple secondary constructors
    2. Use the constructor keyword to define
    3. When there is a primary constructor, the secondary constructor must call the primary constructor
    4. Functional body
class Student(val sno: String, val grade: Int, name: String, age: Int) :Person() {
    //Call the main constructor through this
    constructor(name: String, age: Int) : this("", 0, name, age) {
    }

    constructor() : this("", 0) {
    }
}
  • When a class does not have a primary constructor defined and a secondary constructor defined, it has no primary constructor. Therefore, there is no need to add a () after the parent class name
//Class is not followed by parentheses (), and no primary constructor is defined
class Student : Person {
	//Use constructor to define the secondary constructor, but there is no primary constructor. You can't use this. You can only use super to use the primary constructor of the parent class
    constructor(name: String, age: Int) : super(name, age) {
    }
    //This class has no primary constructor
}

Interface

  • Consistent with Java: single inheritance, multiple implementations
  • The definition method is consistent with Java
  • When implementing the interface, you also use colons:, separated by commas in the middle
//Define interface
interface Study {
    fun readBooks()
    fun doHomework()
}

//The Student class inherits the Person class
class Student(name: String, age: Int) : Person(name, age), Study {
	//Use the override keyword to represent the override method
    override fun readBooks() {
        println(name + " is reading.")
    }

    override fun doHomework() {
        println(name + " is doing homework.")
    }
}

Interface method default implementation

  • KT supports the default implementation of interface functions. The interface implemented by default does not require rewriting. Java also supports this function after JDK 1.8
  • Reuse is easier. If you can only abstract methods, you can only change the interface into abstract classes. However, due to the limitation of single inheritance, this method sometimes doesn't work
interface Study {
    fun readBooks()

    fun doHomework() {
        println("do homework default implementation.")
    }
}

Function visibility modifier

visibility modifiers KotlinJavadifference
publicAll classes visible (default)All classes visibleKT is public by default
privateThe current class is visibleThe current class is visibleidentical
protectedThe current class and subclass are visibleThe current class, subclass and classes under the same package path are visibleThe KT range is small, and the same package is not visible
defaultnothingClasses under the same package path are visible (default)Unique to Java
internalClass visible in the first mock exam modulenothingUnique to KT

Data class

  • Data classes are commonly used. M in MVC, MVP, MVVM and other architecture patterns refers to data classes
  • Data classes generally need to override the methods of equals(), hashCode(), toString(). For Java, these need to be generated manually; KT has special data classes to automatically realize the above functions and avoid writing these function codes
  • Add the open keyword before the class to turn the class into a data volume
//You can omit braces when there is no code in the class
data class phone(val brand: String, val model: String)

Singleton class

  • Singleton mode is very common. Java needs more code to implement singleton mode, but for KT, just change the class keyword to the object keyword, and KT will automatically ensure that it is a singleton
  • Calling a singleton class is similar to calling a static method in Java
//Define singleton class
object Singleton {
    fun singletonTest() {
        println("singletonTest is called.")
    }
}
//Calling a singleton class method
Singleton.singletonTest()

String inline expression

  • To display variables in a string in java, you can only use the + sign connection. This writing method is laborious and error prone
  • KT supports C language printf(), which displays the value of variables by embedding the expression of ${} in the string
"hello, ${obj.name}. nice to meet you!"
//When there is only one variable in the expression, you can omit the braces, ↓
"hello, $name. nice to meet you!"
"Cellphone(brand=$brand, price=$price)"

reference material
First line of code - Android (version 3)
repeat loop

Posted by Jmz on Wed, 22 Sep 2021 07:34:16 -0700