概述
Kotlin定义常量、静态字段、静态方法有三种实现手段,分别是包级、对象、类的伴生对象。
- 常量:由
const val
修饰,只适用于基本类型和字符串。 - 静态字段:kotlin属性添加
@JvmField
注解后,可以暴露成静态字段被Java 调用。 - 静态方法:
1.包级函数会直接编译成静态方法;
2.Kotlin对象函数和伴生对象函数添加@JvmStatic
注解后,编译时会额外生成静态方法。
包级实现在包名前添加@file:JvmName
注解,可以修改生成的 Java 类的类名。
总结
- 天生有归属的,比方说静态工厂方法,建议使用伴生对象。
- 能强行归类的,比方说Constants,建议归类到一个新对象。
- 官方觉得包级方法很酷,但是个人建议慎用,用的不好容易混淆,降低内聚性。
包级
// demo.kt
package demo
const val NAME = "package"
@JvmField
val list = listOf(0, 1, 2, 3)
fun doo(name: String, list: List<Int>) = list.forEach{print(name[it])}
包级重命名
// demo.kt
@file:JvmName("DemoUtils")
package demo
const val NAME = "package"
@JvmField
val list = listOf(0, 1, 2, 3)
fun doo(name: String, list: List<Int>) = list.forEach{print(name[it])}
// 此时的Java调用为
// DemoUtils.doo(DemoUtils.NAME, DemoUtils.list);
对象
// DemoObject.kt
package demo
object DemoObject {
const val NAME = "object"
@JvmField
val list = listOf(0, 1, 2, 3)
@JvmStatic
fun doo(name: String, list: List<Int>) = list.forEach{print(name[it])}
}
伴生对象
// DemoClass.kt
package demo
class DemoClass {
companion object {
const val NAME = "class"
@JvmField
val list = listOf(0, 1, 2, 3)
@JvmStatic
fun doo(name: String, list: List<Int>) = list.forEach{print(name[it])}
}
}
Java调用
// Java.java
public class Java {
public static void main(String[] args) {
DemoKt.doo(DemoKt.NAME, DemoKt.list);
DemoObject.doo(DemoObject.NAME, DemoObject.list);
DemoClass.doo(DemoClass.NAME, DemoClass.list);
}
}
Kotlin调用
// kotlin.kt
fun main(args: Array<String>) {
doo(NAME, list)
with(DemoObject) {
this.doo(this.NAME, this.list)
}
DemoClass.doo(DemoClass.NAME, DemoClass.list)
}
官方觉得很酷,个人建议慎重使用,至少在想明白以下几点时慎重使用。
- 类似Java中的import static。在现代IDE里,少敲代码优点几乎不存在,容易混淆的缺点依然存在。
- Kotlin引入非本包的包级成员,忽略包名的话非常容易混淆,带上小写包名看得浑身不自在(强迫症)。
- 强迫症。Java调用和Kotlin调用形式上有差别,Java多了一层XxxxKt,即使使用JvmName指定名称,还是多出一层。
Java调用方法 官网 中文
在 org.foo.bar 包内的 example.kt 文件中声明的所有的函数和属性,包括扩展函数, 都编译成一个名为 org.foo.bar.ExampleKt 的 Java 类的静态方法。
网友评论