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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。