kotlin伴生對象

Kotlin中沒有靜態成員,主要原因在於它允許包級屬性和函數的存在;Kotlin爲靜態成員提供了多種替代的方案:

使用包級屬性和函數:主要用於全局常量和工具函數;
使用伴生對象:主要用於與類有緊密聯繫的變量和函數;
使用@JvmStatic註解:與伴生對象搭配使用,將變量和函數聲明爲真正的JVM靜態成員。

伴生對象

Kotlin中的對象指的是使用object關鍵字定義的類型聲明,一般用作單例模式和伴生對象。
object讓創建單例變得十分簡單:

object Resource{
    val name="Alex"

    fun say(){
        println("Hello")
    }
}

用Java表示如下:

public final class Resource {
  public static final Resource INSTANCE;
  private static final String name = "Alex";
  
  static {
    new Resource();
  }
  
  private Resource() {
    INSTANCE = this;
  }
  
  public static final String getName() {
    return name;
  }
  
  public static final say() {
    System.out.println("Hello")
  }
}

name和say()雖然不是包級成員,但被編譯成了靜態成員。
Kotlin允許在類中使用companion object創建伴生對象,用伴生對象的成員來代替靜態成員:

class Person(val name:String){
    companion object {
        val anonymousPerson=Person("Anonymous")
        fun sayHello(){
            println("Hello")
        }
    }

    var age=0
    fun sayName(){
        println("My name is $name")
    }
}

用Java表示如下:

public final class Person {
  private final int age;
  private final String name;
  private static final Person anonymousPerson = new Person("Anonymous");
  public static final Person.Companion Companion = new Person.Companion();
  
  public Person(String name) {
    this.name = name;
  }
  // getAge()、setAge()、getName()
  
  public final void sayName() {
    System.out.println("My name is " + this.name);
  }
  
  public static final class Companion {
    private Companion() {}
    
    public final Person getAnonymousPerson() {
      return Person.anonymousPerson;
    }
    
    public final void sayHello() {
      System.out.println("Hello")
    }
  }
}

使用伴生對象實際上是在這個類內部創建了一個名爲Companion的靜態單例內部類,伴生對象中定義的屬性會直接編譯爲外部類的靜態字段,而函數會被編譯爲伴生對象的方法。
Person的方法調用如下:

fun main(args: Array<String>) {
    Person.anonymousPerson
    Person.sayHello()
    val person = Person("HXL")
    person.sayName()
}

@JvmStatic註解

JvmStatic註解只能用在伴生對象裏,修飾伴生對象內的屬性和函數,用來告訴編譯器屬性和函數編譯爲真正的JVM靜態成員。
如果在伴生對象聲明裏使用@JvmStatic註解,name沒有加該註解的屬性和函數將不會被編譯爲靜態成員:

class Person(val name: String) {
  companion object {
    @JvmStatic val anonymous = Person("Anonymous")
    fun say() = println("Hello")
  }
}

這個伴生對象中定義了兩個成員,anonymous使用@JvmStatic註解修飾,會被編譯爲Person類的靜態成員Kotlin和Java中都可以用Person.anonymous來調用它;而say()方法沒有用@JvmStatic註解修飾,會被編譯爲Person.Companion類的成員,Kotlin中可以用Person.say()來調用,但Java中只能用Person.Companion.say()調用。

作者:Hunter_Arley
鏈接:https://www.jianshu.com/p/807555aae65a
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章