Kotlin中的"静态方法"

在Kotlin中,弱化了静态方法这个概念,使得我们想要创建静态方法变得不那么直观,并且,有些方式创建出来的"静态方法"还不是真正的静态方法,这里一一介绍

假的静态方法

使用这类方式创建出来的"静态方法"只是在调用上看起来像是静态方法,但在jvm看来并不是

单例类 object

使用object关键字标注的类会被视为单例类,Kotlin会保证这个类在运行时不会有两个及以上的实例存在,例如:

1
2
3
4
5
object Utils {
fun reportException(e: Exception) {
// ...
}
}

调用上述方法的方式是(Kotlin调用):

1
Utils.reportException(e)

这看起来就像是静态方法,但其实并不是,如果一个Java文件想调用此方法,必须这样写(Java调用):

1
Utils.INSTANCE.reportException(e)

伴生对象 companion object

当一个类中的一些方法是静态,另一些不需要是静态时,就可以采用这种方法

1
2
3
4
5
6
7
8
9
10
11
class CompanionObjectTest {
fun hello(){
println("Hello")
}

companion object {
fun staticHello(){
println("static hello")
}
}
}

调用staticHello(Kotlin调用):

1
CompanionObjectTest.staticHello()

Java调用:

1
CompanionObjectTest.Companion.staticHello();

可以看到上面这两种方式定义的静态方法,对于Java来说都不是真正的静态方法

真的静态方法

@JvmStatic注解

在Kotlin中的object类或 companion object 中的方法上使用@JvmStatic注解,即可将该方法声明为真正的静态方法

注意,该注解只能用在objectcompanion object中的方法上,用在其他方法上会报错

例如我们上面的例子:

1
2
3
4
5
6
object Utils {
@JvmStatic
fun reportException(e: Exception) {
// ...
}
}
1
2
3
4
5
6
7
8
9
10
11
12
class CompanionObjectTest {
fun hello(){
println("Hello")
}

companion object {
@JvmStatic
fun staticHello(){
println("static hello")
}
}
}

对于Kotlin,调用方式不变,对于Java,现在可以这样调用:

1
2
Utils.reportException(e)
CompanionObjectTest.staticHello()

并且,原来没加@JvmStatic注解时的调用方式仍然可用,这是因为Kotlin会为@JvmStatic注解的方法生成两份同名方法,一份是静态方法,一份是成员方法

顶层函数

Kotlin中的顶层函数指的是声明在一个文件顶层,没有被任何类包裹的函数

例如:

Utils.kt

1
2
3
fun reportException(e: Exception) {
// ...
}

在Kotlin中调用这个函数直接输入函数名即可,无需任何前缀

但是Java中没有顶层函数这个概念,应该如何调用呢?答案是,其实Kotlin最终会为所有顶层函数自动生成一个类,并且将这些顶层函数作为该类的静态方法,这个类的名称就是文件名(不含扩展名)Kt,例如我们上面的例子就是:UtilsKt,在Java中,我们直接引用这个类即可:

1
UtilsKt.reportException(e)