簡介
Kotlin基本語法對比
本篇文章主要是為了方便Android開發(fā)者從Java轉(zhuǎn)到Kotlin初期的迷茫,提供兩種語言基礎(chǔ)語法的對比勃黍,方便理解
1 聲明(常量與變量)
在Kotlin中,聲明變量有兩個關(guān)鍵字榜田,它們是val與var
var
:可重新賦值的變量使用var
關(guān)鍵字锻梳,代表著變量(可讀可寫)
val
:只能為其賦值一次的變量使用val
關(guān)鍵字疑枯,代表變量(只讀),跟final有略微不同
通過代碼來對比
Kotlin:
val a: Int = 1 // 立即賦值
val b = 2 // 自動推斷出 `Int` 類型
var c = 0 // 自動推斷出 `Int` 類型
c = 1
Java:
final int a = 1;
final int b = 2;
int c;
c = 3;
簡單的對比可以比較清晰的看出來:
var
:定義變量的時候不帶final
val
:相當于定義變量的時候帶final
废亭,但是跟final
又有略微的不同,到底有什么區(qū)別呢液兽?請看接下來的"屬性與字段"
1.1 屬性與字段
首先我們需要區(qū)分一下屬性和字段
Kotlin中聲明的變量掌动,都是屬性
Java中聲明的變量,都是字段
接下來我們看看在Kotlin中聲明一個變量的完整步驟來更好的理解:
class KotlinTest {
val a = 1
var b = 2//屬性
}
通過Decompile轉(zhuǎn)換成Java看一下具體的操作
public final class KotlinTest {
private final int a = 1;
private int b = 2; //第一部分創(chuàng)建字段
public final int getA() {
return this.a;
}
//第二部分創(chuàng)建get()
public final int getB() {
return this.b;
}
//第三部分創(chuàng)建set()
public final void setB(int var1) {
this.b = var1;
}
}
小結(jié):
-
val
聲明的是屬性柑晒,final
聲明的是字段 - Kotlin中屬性的聲明 = Java中字段聲明 + get() + set()
- 而被
val
聲明的屬性是沒有set() - 盡量用
val
匙赞,為什么要設(shè)置這兩個類型聲明,因為當變量不可變的時候妖碉,建議使用final
標記,但是很多同學(xué)在寫的時候覺得麻煩坐榆,沒省略了final
鱼鸠,為了代碼的安全性羹铅,設(shè)置了val
,省略了寫final
的步驟麻蹋,更適合讓同學(xué)們使用
1.2 幕后字段 field
在 Kotlin 類中不能直接聲明字段焊切,聲明的是屬性。而屬性是不能保存狀態(tài)的刹勃,只有字段才能保存狀態(tài)嚎尤,所以Kotlin在屬性聲明的時候,會默認創(chuàng)建一個字段乏梁,叫做“幕后字段”。
var counter = 0 // 注意:這個初始器直接為幕后字段賦值
set(value) {
if (value >= 0) field = value// 注意:并不是直接賦值給counter卖毁,而是賦值給幕后字段
}
1.3 延時屬性 lateinit
一般地落萎,屬性聲明為非空類型必須在構(gòu)造函數(shù)中初始化模暗。比如:
var a: Person = Person()
但是我們在使用Java的時候,經(jīng)常是創(chuàng)建一個變量碍侦,并不會立即給賦值隶糕,比如:
private Person p;
這種情況下,你可以用lateinit
修飾符標記該屬性:
lateinit var a: Person
在初始化前訪問一個lateinit
屬性會拋出一個特定異常濒旦,該異常明確標識該屬性被訪問及它沒有初始化的事實再登。要檢測一個 lateinit var
是否已經(jīng)初始化過,請在該屬性的引用上使用 .isInitialized
:
if (::a.isInitialized) {
println(a.name)
}
使用lateinit修飾符的時候梯嗽,需要注意以下幾點:
- 該修飾符只能用于在類體中的屬性
- 只能修飾var沽损,不能修飾val
2 類型
Kotlin:
val a: Int = 1 // 立即賦值
val b = 2 // 自動推斷出 `Int` 類型
val c: Int // 如果沒有初始值類型不能省略
c = 3 // 明確賦值
Java:
public final int a = 1;
public final int b = 2;
public final int c = 3;
通過上面的對比绵估,可以發(fā)現(xiàn)Kotlin與Java之間有以下幾點差別
- 寫法上有區(qū)別:
Kotlin:<屬性名>: <數(shù)據(jù)類型>
Java:<數(shù)據(jù)類型> <屬性名> - Kotlin可以推斷出屬性類型,Java需要必須手動設(shè)置
3 空安全
在Java中形入,最常見的異常就是被稱之為《十億美元的錯誤》缝左。就是訪問空引用的成員會導(dǎo)致空引用異常, NullPointerException 或簡稱 NPE崩掘。而Kotlin 的類型系統(tǒng)旨在消除來自代碼空引用的危險。
3.1 可空類型與非空類型
在Kotlin中诵原,一個變量想要允許為空挽放,必須加上?
Kotlin:
var a: String = "abc"
a = null // 編譯錯誤
var b: String?
b = null // ok
print(b)
val la = a.length // 正確:變量"a"不可能為空辑畦,放心使用
val lb = b.length // 錯誤:變量"b"可能為空
val lb2 = b?.length //正確:當變量"b"為空時,返回null
Java:
public String a = "abc";
a = null; //ok
3.2 空判斷
在條件中檢查null:
Kotlin:
val b: String? = null
val l = if (b != null) b.length else -1
Java:
String b = null;
final int l;
if (b != null){
l = b.length();
}else{
l = -1;
}
空安全的調(diào)用:
Kotlin:
val a = "Kotlin"
val b: String? = null
println(b?.length)
println(a?.length) // 無需安全調(diào)用
//鏈式調(diào)用
val name = bob?.department?.head?.name
Java:
final String a = "Kotlin";
final String b = null;
if (b == null){
System.out.print("null");
}else {
System.out.print(b.length());
}
System.out.println(a.length());
//鏈式調(diào)用
final String name;
if (bob != null) {
if (department != null) {
if (head != null) {
name = bob.department.head.name;
}
}
}
小結(jié):
- 在Kotlin中蚯妇,所有允許為null的變量必須添加
?
- 當調(diào)用的時候箩言,對象為null的時候焕襟,會返回null,而不是報NPE錯誤
- 在鏈式調(diào)用中务漩,如果任意一個屬性(環(huán)節(jié))為空它褪,這個鏈式調(diào)用就會返回 null。
4 總結(jié)
本文只是簡單的對比了Kotlin與Java的語法上的區(qū)別宏悦,然后Kotlin并不是這么簡單包吝,需要深入學(xué)習(xí)才能掌握诗越。希望對大家有所幫助息堂,如果文章有不足之處块促,請不吝指出床未,謝謝薇搁。