Kotlin變數宣告的val和var

Tue, Nov 2, 2021 閱讀時間 1 分鐘

In Kotlin, everything is an object in the sense that we can call member functions and properties on any variable.

在Kotlin所有的變數都是物件,可以呼叫它的成員函數和屬性,宣告會用到兩個關鍵字是val和var

  • val:用在唯讀(read-only)變數,只能賦值一次,類似在java中加上final,建議優先使用
  • var:是可變(mutable)變數,值可以被修改,當需要重新給值的情況再改用var

kotlin的變數和函數可以單獨存在檔案(module)的top level,不用像java都要依附在類別裡,可以見如下例子
💯IntelliJ生產力小提示:輸入mainsout再按Tab就可以快速展開一段Code Template

fun main() {
    val a: Int = 1 // 宣告並直接給值
    val b = 2 // 根據初始值做型別推斷得出型態是Int
    val c: Int // 延後給值,所以必須指定型態
    c = 3
    // c = 4 錯誤,val不能重新給值
    var d = 4 // local variable
    d = 5

    incrementX()
    println(x)

    val person = Person() // kotlin的物件不用new
    // person = Person() 錯誤,val不能再指向其它物件
    person.age = 36 // 指向的物件本身可以去改變其中的屬性
    println("age=${person.age}")
}

var x = 0 // top level property
fun incrementX() {
    x += 1
}

class Person {
    val name = "Ryan" // class read-only property
    var age = 35 // class mutable property
}

變數宣告在頂層屬性或是類別屬性時,kotlin編譯器會自動生成屬性的getter和setter,存取屬性只需要使用屬性名稱,而區域變數就只是一般的變數,不會有getter和setter,來看一下前面例子Person類別翻譯回java的樣子就很清楚了,kotlin是一種JVM language,它的bytecode一樣可以反編譯回java的原始碼
💯IntelliJ生產力小提示:Tools > Kotlin > Show Kotlin Bytecode 再點Decompile

public final class Person {
   @NotNull
   private final String name = "Ryan";
   private int age = 35;

   @NotNull
   public final String getName() {
      return this.name;
   }

   public final int getAge() {
      return this.age;
   }

   public final void setAge(int var1) {
      this.age = var1;
   }
}

因為name宣告成val所以只有getter,沒有setter,這表示我們只能取用它,但是不代表它的值是不可變(immutable)的,可以透過自定義的getter來改變它,只是無法直接更新它的值,參考官方定義的說明