Kotlin基礎(chǔ)語法學(xué)習(xí)之變量(Java To Kotlin)

簡介

Kotlin基本語法對(duì)比
本篇文章主要是為了方便Android開發(fā)者從Java轉(zhuǎn)到Kotlin初期的迷茫,提供兩種語言基礎(chǔ)語法的對(duì)比,方便理解

1 聲明(常量與變量)

在Kotlin中,聲明變量有兩個(gè)關(guān)鍵字,它們是val與var
var:可重新賦值的變量使用var關(guān)鍵字,代表著變量(可讀可寫)
val:只能為其賦值一次的變量使用val關(guān)鍵字,代表變量(只讀),跟final有略微不同

通過代碼來對(duì)比
Kotlin:

val a: Int = 1  // 立即賦值
val b = 2   // 自動(dòng)推斷出 `Int` 類型
var c = 0  // 自動(dòng)推斷出 `Int` 類型
c = 1

Java:

final int a = 1;
final int b = 2;
int c;
c = 3;

簡單的對(duì)比可以比較清晰的看出來:
var:定義變量的時(shí)候不帶final
val:相當(dāng)于定義變量的時(shí)候帶final,但是跟final又有略微的不同,到底有什么區(qū)別呢?請(qǐng)看接下來的"屬性與字段"

1.1 屬性與字段

首先我們需要區(qū)分一下屬性和字段
Kotlin中聲明的變量,都是屬性
Java中聲明的變量,都是字段
接下來我們看看在Kotlin中聲明一個(gè)變量的完整步驟來更好的理解:

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è)置這兩個(gè)類型聲明,因?yàn)楫?dāng)變量不可變的時(shí)候,建議使用final標(biāo)記,但是很多同學(xué)在寫的時(shí)候覺得麻煩,沒省略了final,為了代碼的安全性,設(shè)置了val,省略了寫final的步驟,更適合讓同學(xué)們使用

1.2 幕后字段 field

在 Kotlin 類中不能直接聲明字段,聲明的是屬性。而屬性是不能保存狀態(tài)的,只有字段才能保存狀態(tài),所以Kotlin在屬性聲明的時(shí)候,會(huì)默認(rèn)創(chuàng)建一個(gè)字段,叫做“幕后字段”。

var counter = 0 // 注意:這個(gè)初始器直接為幕后字段賦值
    set(value) {
        if (value >= 0) field = value// 注意:并不是直接賦值給counter,而是賦值給幕后字段
    }

更多幕后屬性相關(guān)請(qǐng)點(diǎn)擊查看

1.3 延時(shí)屬性 lateinit

一般地,屬性聲明為非空類型必須在構(gòu)造函數(shù)中初始化。比如:

var a: Person = Person()

但是我們?cè)谑褂肑ava的時(shí)候,經(jīng)常是創(chuàng)建一個(gè)變量,并不會(huì)立即給賦值,比如:

private Person p;

這種情況下,你可以用lateinit修飾符標(biāo)記該屬性:

lateinit var a: Person

在初始化前訪問一個(gè)lateinit屬性會(huì)拋出一個(gè)特定異常,該異常明確標(biāo)識(shí)該屬性被訪問及它沒有初始化的事實(shí)。要檢測(cè)一個(gè) lateinit var 是否已經(jīng)初始化過,請(qǐng)?jiān)谠搶傩缘囊蒙鲜褂?.isInitialized

if (::a.isInitialized) {
    println(a.name)
}

使用lateinit修飾符的時(shí)候,需要注意以下幾點(diǎn):

  • 該修飾符只能用于在類體中的屬性
  • 只能修飾var,不能修飾val

更多l(xiāng)ateinit相關(guān)請(qǐng)點(diǎn)擊查看
更多屬性與字段相關(guān)請(qǐng)查看

2 類型

Kotlin:

val a: Int = 1  // 立即賦值
val b = 2   // 自動(dòng)推斷出 `Int` 類型
val c: Int  // 如果沒有初始值類型不能省略
c = 3       // 明確賦值

Java:

public final int a = 1;
public final int b = 2;
public final int c = 3;

通過上面的對(duì)比,可以發(fā)現(xiàn)Kotlin與Java之間有以下幾點(diǎn)差別

  • 寫法上有區(qū)別:
    Kotlin:<屬性名>: <數(shù)據(jù)類型>
    Java:<數(shù)據(jù)類型> <屬性名>
  • Kotlin可以推斷出屬性類型,Java需要必須手動(dòng)設(shè)置

3 空安全

在Java中,最常見的異常就是被稱之為《十億美元的錯(cuò)誤》。就是訪問空引用的成員會(huì)導(dǎo)致空引用異常, NullPointerException 或簡稱 NPE。而Kotlin 的類型系統(tǒng)旨在消除來自代碼空引用的危險(xiǎn)。

3.1 可空類型與非空類型

在Kotlin中,一個(gè)變量想要允許為空,必須加上?
Kotlin:

var a: String = "abc"
a = null // 編譯錯(cuò)誤
var b: String?
b = null // ok
print(b)
val la = a.length // 正確:變量"a"不可能為空,放心使用
val lb = b.length // 錯(cuò)誤:變量"b"可能為空
val lb2 = b?.length //正確:當(dāng)變量"b"為空時(shí),返回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)用

//鏈?zhǔn)秸{(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());

//鏈?zhǔn)秸{(diào)用
final String name;
if (bob != null) {
    if (department != null) {
        if (head != null) {
            name = bob.department.head.name;
        }
    }
}

小結(jié):

  • 在Kotlin中,所有允許為null的變量必須添加?
  • 當(dāng)調(diào)用的時(shí)候,對(duì)象為null的時(shí)候,會(huì)返回null,而不是報(bào)NPE錯(cuò)誤
  • 在鏈?zhǔn)秸{(diào)用中,如果任意一個(gè)屬性(環(huán)節(jié))為空,這個(gè)鏈?zhǔn)秸{(diào)用就會(huì)返回 null。

更多空相關(guān)的請(qǐng)點(diǎn)擊查看

4 總結(jié)

本文只是簡單的對(duì)比了Kotlin與Java的語法上的區(qū)別,然后Kotlin并不是這么簡單,需要深入學(xué)習(xí)才能掌握。希望對(duì)大家有所幫助,如果文章有不足之處,請(qǐng)不吝指出,謝謝。

更多Kotlin相關(guān)的請(qǐng)點(diǎn)擊查看

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容