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 type | Kotlin object data type | explain |
---|---|---|
int | Int | integer |
long | Long | Long integer |
short | Short | Short |
float | Float | Single precision floating point |
double | Double | Double precision floating point |
boolean | Boolean | Boolean |
char | Char | character |
byte | Byte | Byte 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:
- Built in break;
- Any type of parameter can be passed, even without parameters;
- 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:
- Each class can have only one primary constructor
- Class has a primary constructor without parameters by default
- You can add parameters
- 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:
- A class can have multiple secondary constructors
- Use the constructor keyword to define
- When there is a primary constructor, the secondary constructor must call the primary constructor
- 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 | Kotlin | Java | difference |
---|---|---|---|
public | All classes visible (default) | All classes visible | KT is public by default |
private | The current class is visible | The current class is visible | identical |
protected | The current class and subclass are visible | The current class, subclass and classes under the same package path are visible | The KT range is small, and the same package is not visible |
default | nothing | Classes under the same package path are visible (default) | Unique to Java |
internal | Class visible in the first mock exam module | nothing | Unique 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