Before the order

At Google I/O 19, Kotlin became the language of choice for Android development. The famous OkHttp has been rewritten in Kotlin. It’s time to consolidate Kotlin’s basics with a blog summary.

(1) Grammatical changes

  • The new keyword is not needed to create objects
  • Statement not required; End, add; It doesn’t matter
  • The variable type is postpended, that is, the variable name comes before the variable type. For example the STR: String
  • Use println() instead of system.out.println ()

(2) Define variables

Kotlin uses the val keyword to declare constants (that is, variables cannot be reassigned after initialization) and the var keyword to declare variables.

Variables can be defined without showing the specified type, and the compiler makes inferences based on the type of their initializer.

Var daqi = 1 var daqi = 1 val a :String ="daqi"// If the variable has no initializer, its type needs to be explicitly specified: val c: Int c = 3Copy the code

When the compiler is able to ensure that only one initialization statement will be executed for the val variable, it can be initialized to different values depending on the condition.

val daqi:String
var isChange = true
if (isChange){
   daqi = "1"
}else{
   daqi = "2"
}
Copy the code

The reference to the val variable is itself immutable, but the object it points to is mutable.

val languages = arrayListOf("Java")
languages.add("Kotlin")
Copy the code

The var keyword allows a variable to change its value, but not its type.

Var daqi = 1 // Compilation does not pass daqi =""
Copy the code

Kotlin uses the fun keyword to declare functions. Complete function definition:

Modifier (default public) + fun + method name + (argument list) : return value {function body}Copy the code

public fun daqi(name:String):String {
}
Copy the code

Expression function body

When a single expression forms a complete function body, the {} and return statements can be removed directly, and the compiler will automatically infer the return value type of the function. Such functions are called expression functions.

fun sum(a: Int, b: Int) = a + b
Copy the code

The difference between statements and expressions is that:

  • Expressions have values and can be used as part of another expression;
  • A statement always surrounds the top-level element in its code block and has no value of its own.

In Java, all control structures are statements. In Kotlin, most control structures except for loops (for, do, and do/while) are expressions (for example, if, when, and try are expressions)

Expression functions are used not only in simple single-line functions, but also in functions that evaluate more complex single expressions.

fun max(a: Int, b: Int ) = if (a > b) a else b
Copy the code

A function that returns no value

A Java-like function with a return type of void

fun daqi():Unit{
}
Copy the code

The Unit type can be omitted

fun daqi(){
}
Copy the code

(3) String template

In Java, when a variable description and its value need to be printed, it is usually printed as follows:

String str = "daqi";
System.out.println("str = " + str);
Copy the code

Kotlin supports string templates, which can reference local variables in a string, but you need to prefix the variable name with $. The expression is statically checked, and if $references a variable that does not exist, the code will not compile.

val str = "daqi"
printlin("str = $str")
Copy the code

$is not limited to simple variable names, but can refer to more complex expressions.

Val daqi = intArrayOf(1,2,3)"${daqi[0]}")
Copy the code

Double quotes can be nested directly within the expression referenced by $(that is, in curly braces {})

println("The first element of daqi:${if(daqi.size > 0) daqi[0] else "null"}")
Copy the code

When you need to print the $sign, you can escape it, or print it with an expression:

// Print the result:$str
val str = "daqi"
println("\$str")
println(The ${} '$'daqi)
Copy the code

(4) Classes and attributes

Define a simple class in Java:

public class Person{
    private final String name;
    
    public Person(String name){
        this.name = name;
    }
    
    public String getName() {returnname; }}Copy the code

Person class written with Kotlin (public by default)

class Person(val name:String)
Copy the code

Extension: If you want to know the specific Java implementation of Kotlin, you can decomcompile the Kotlin file using the idea tool:

Tools ->Kotlin -> Show Kotlin Bytecode -> right side of the Bytecode box -> upper-left Decompile button

Setter and getter

In Kotlin, when you declare attributes, you also declare accessors (get and set).

The val property has only a getter, and the var property has both a getter and a setter. Complete syntax for declaring an attribute:

var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]
Copy the code

Initializers, getters, and setters are optional. If the type can be inferred from an initializer or getter return value, it can also be omitted. The default implementation of accessors is very simple: returns and changes to corresponding variables.

When you need to provide additional logic when a value is accessed or modified, you can use custom getters and setters

Custom getter

Implementation in Kotlin

class Rectangle(val height:Int,val width:Int){
    val isSquare:Boolean
        get() {return height == width
    	}
}
Copy the code

Corresponding Java implementation:

Custom setter

Implementation in Kotlin:

class Rectangle(val height:Int,val width:Int){
    var isSquare:Boolean = false
        set(value) {
            field = value
        }
}
Copy the code

In setter methods, the special identifier field is used to access the value of the supporting field (the background field). The details of the background field will be discussed later.

Note:

In Kolin, a variable whose name begins with is. When converted to the corresponding Java GET and set methods, getters do not add any precursors, and is in setter names is replaced with set.

class Person(
    var isDaqi:Boolean = false
)
Copy the code

The accessor to this object in Java is:

(5) Iteration

Kotlin’s while and do-while loops have the same syntax as Java’s.

The for loop, on the other hand, exists only in one form, much like for-each. But instead of in:

fun iterationArray(args:Array<String>){
    for (str in args) {

    }
}
Copy the code

The for loop can also traverse the interval. An interval is essentially the interval between two values. Use.. The operator represents an interval.

The interval in Kotlin is a closed interval, that is, the end value is also part of the interval. The default interval iteration step is 1.

val oneToTen = 1.. 10Copy the code

You can change the step by using the step keyword. During the traversal, the growth range of variable I will change to 2, that is, it will increase by 2 with each iteration.

for(i in0.. 100 step 2){ }Copy the code

If you want a semi-closed interval, where the end value is not part of the interval, you can use the until keyword,

val oneToNine = 1 until 10
Copy the code

Use the downTo keyword if you need a reverse order interval

val tenToOne = 10 downTo 1
Copy the code

At this point, the cycle will decrease from 10 to 1. The interval represented by downTo is also a closed interval.

If you want to loop over data indexes like a normal for loop, you can use indices for arrays

for (i in args.indices) {
    println(args[i])
}
Copy the code

(6), if expression

In Kotlin, if is an expression, that is, it returns a value.

When the if branch is a code block, the final expression will be the value of that code block:

val max = if (a > b) {
    print("Choose a")
    a
} else {
    print("Choose b")
    b
}
Copy the code

(7) when expression

When in Kotlin, which corresponds to switch in Java, is much more powerful.

When compares its arguments to all the branch criteria in order until a branch meets the criteria and executes its branch code. When multiple branches need to be treated in the same way, they can be placed together, separated by commas.

When used as an expression, there must be an else branch, unless the compiler detects that all possible cases have been overridden. (For example, enumeration classes)

when (x) {
    0, 1 -> print("x == 0 or x == 1"2 - >)print("x == 2")
    else -> print("otherwise")}Copy the code

Have you noticed that there are no complicated cases and breaks!!

The parameter when is optional and of unlimited type! And you can use any expression as a branching condition. (Switch requires constant as branch condition ~)

When is the function body of the expression function, which uses the parameters of the function directly without setting parameters. And use in or! In conditional statements. In determines whether a variable is in an interval or set.

fun daqi(num:Int,intArray: IntArray) = when{
    num in1.. 10 - >"1 ~ 10"
    num !in intArray -> "no in Array"
    else -> "other"
}
Copy the code

When can also be used to replace if-else if chains.

fun daqi(num:Int) = when{
    num < 0 -> "Less than zero"
    num >0 && num < 10 -> "1.. 10"
    else -> "other"
}
Copy the code

Is can check whether a variable is of a certain type, and with intelligent conversion (after checking the type of a variable, it does not need to be converted, and can be used as the checked type), it is very convenient to perform type safety operations.

Object fun daqi(num:Any) = when(num){is String -> {"This variable is of type String, get its length.") println(num. Length)} is Int -> {"This variable is of type Int, compare it to 10.")
            num.rangeTo(10)
    }
    else -> "other"
}
Copy the code

(8) Exceptions in Kotlin

Kotlin’s exception handling is similar to Java. When an exception is thrown, you do not need to use the new keyword to create an exception instance.

var daqi:String? = null
if (daqi == null){
    throw NullPointerException("daqi is null")}Copy the code

Try can also be an expression assigned to a variable. When the code executes properly, the last expression in the try block is the result, and if an exception is caught, the last expression in the catch block is the result. The contents of the finally block do not affect the result of the expression.

fun readNumber(reader:BufferedReader):Int? = try{
    Integer.parseInt(reader.readLine())
}catch(e:NumberFormatException){
    null
}catch (e:NullPointerException){
    null
}finally {
    reader.close()
}
Copy the code

There can be anywhere from zero to multiple catch blocks. The finally block can be omitted. But there should be at least one catch and finally block.

(9) enumeration

Kotlin declares enumerated classes with the keywords enum and class. Enum is a soft keyword that has special meaning only when it comes before class.

Declare a normal enumeration class:

enum class Color{
    RED,BLUE
}
Copy the code

Declare an enumerated class with attributes:

Enum class Color(val r:Int,val g:Int,val b:Int){RED(255,0,0),BLUE(0,0,255); fun rgb = (r * 256 + g) * 256 + b }Copy the code

If you define any method in an enumeration type, use a semicolon; Separate enumeration constant lists from method definitions.

References:

  • Kotlin in Action
  • Kotlin website

Android Kotlin series:

Kotlin’s Knowledge generalization (I) — Basic Grammar

Kotlin knowledge generalization (2) – make functions easier to call

Kotlin’s knowledge generalization (iii) — Top-level members and extensions

Kotlin knowledge generalization (4) – interfaces and classes

Kotlin’s knowledge induction (v) — Lambda

Kotlin’s knowledge generalization (vi) — Type system

Kotlin’s knowledge induction (7) — set

Kotlin’s knowledge induction (viii) — sequence

Kotlin knowledge induction (ix) — Convention

Kotlin’s knowledge induction (10) — Delegation

Kotlin’s knowledge generalization (xi) — Higher order functions

Kotlin’s generalization of knowledge (xii) – generics

Kotlin’s Generalization of Knowledge (XIII) — Notes

Kotlin’s Knowledge induction (xiv) — Reflection