在描述 Kotlin 中的 Top-level (顶级声明)
之前,我们先熟悉一下 Kotlin 中文件的概念。理解了 Kotlin 文件的概念,对于理解 Top-level
的相关有所帮助。
1. Kotlin 文件
在 Kotlin 项目目录中, 文件是以 .kt
为后缀名,表示这是一个 Kotlin 文件。
1.1 命名规范
对文件的命名最好符合编码规范,方便自己、方便他人。
- 当 Kotlin 文件包含单个类,那么文件的名字应与类名相同,并以 .kt 为后缀。
- 当Kotlin 文件保包含多个类或者只包含顶级声明(top-level),那么选择一个可以描述文件内容的名称作为该文件的名字。
总的来说,命名最好可以描述该文件内容。
1.2 源文件组织
鼓励多个声明(类、顶级函数或者属性)放在同一个 Kotlin 源文件中, 只要这些声
明在语义上彼此紧密关联并且文件保持合理大小 (不超过几百行)。
特别是在为类定义与类的所有客户都相关的扩展函数时, 请将它们放在与类自身定
义相同的地方。而在定义仅对指定客户有意义的扩展函数时,请将它们放在紧挨该
客户代码之后。不要只是为了保存 “类的所有扩展函数”而创建文件。这段话的意思就是告诉我们不要随意新建 Kotlin 文件,这样保证项目的大小不会急速扩大。
2. Top-level
首先需要声明的是 Top-level
是在 Kotlin 中有的概念,在 Java 中是不存在这样的概念的。
2.1 什么是 Top-level
在 Java 中,类是所有的属性、动作的根基点,即一切的声明都依托于类,如下所示
class People{
private int age;
private String name;
public void setName(String name){
this.name = name
}
.....
}
很明显,所有的字段和方法必须存在于一个类中。
而在 Kotlin 中这一规则不复存在,属性和方法可以完全 脱离于类
而单独的声明。
People.kt
文件具体内容如下:
@file:JvmName("KK")
package unitTwo
//top-level 接口
interface Human {
fun sex(): String
fun country(): String
}
//top-level 类
class ChineseMan(var sex: String, var country: String) : Human {
override fun sex() = sex
override fun country() = country
}
//top-level 属性
val people = ChineseMan("man", "China")
//top-level 方法
fun main(args: Array<String>) {
println("${people.sex} --- ${people.country}")
}
执行 main() 方法,打印日志为:man --- China
上面 Kotin 文件的正确运行也进一步验证了在 Kotlin 中属性、方法、接口、类等是不依托于类在存在。
2.2 Top-level 的引用
Kotlin 与 Java 毕竟分属于两种不同的语言,其自调和互调的方法肯定是不同的,这些是在日常开发中需要注意的。
2.1 在 Kotlin 中引用 Top-level
2.1.1 同一包文件下,直接调用
TopLevelTest.kt
具体代码如下:
@file:JvmName("KK")
package unitTwo
fun show(name: String) {
println("name is ${name}")
}
具体在 Main 类中调用 TopLevelTest.kt
文件中的 show
方法
package unitTwo
//import show
object MainObj {
@JvmStatic
fun main(args: Array<String>) {
show("mike")
}
}
打印日志为:name is mike
。
当然你也可以将 show 方法通过 impor 的方式引入,不过在同包下可以不写。
注意:不会存在同包下两个文件存在相同的方法或其他相关内容,因为编译器会报出 方法冲突异常 。
2.1.2 不同一包,import 后调用
相同的,我们还是调用 unitTwo/TopLevelTest.kt
文件中的 show
方法,不过现在调用方为位于 unitOne 下的 Main 类:
package unitOne
import unitTwo.show // 首先 import show 方法
object MainObj {
@JvmStatic
fun main(args: Array<String>) {
show("aline")
}
}
打印日志为:name is aline
,说明我们已经成功完成调用。
注意: 在 Kotlin 中 import 的为 相应文件的方法名 :
import unitTwo.show
2.2 在 Java 中引用 Top-level
Kotlin 文件中的 top-level 相关内容再编译成 Jvm 字节码后,其作用就相当于 Java 中的一个个静态内容,
其对应关系为:
top-level 方法 –> 静态方法
不过需要注意的是在 Java 中识别 Kotlin 文件的格式: 文件名Kt
, 这样使用在 Java 中才是合法的。
那么如何在 Java 中调用 top-level 相关内容呢?同样分为同包和不同包文件目录。
2.2.1 同一包文件下,通过文件名直接调用
public class Main {
public static void main(String[] strs){
TopLevelTestKt.show("John");
}
}
打印信息为: name is John
2.2.2 不同一包文件下,import 后通过文件名直接调用
package unitTwo;
import unitOne.TestKt;
public class Main {
public static void main(String[] strs){
TestKt.show("Mary");
}
}
打印信息为:name is Mary
当然如果你想自定义 Java 代码调用 Kotlin 文件的名字,可以使用 @file:JvmName("xxx")
,如下所示:
TopLevelTest.kt
具体代码如下:
@file:JvmName("KK")
package unitTwo
fun show(name: String) {
println("name is ${name}")
}
Main.java
具体代码如下:
package unitOne;
import unitTwo.KK;
public class Main {
public static void main(String[] strs) {
KK.show("fsdf");// 直接使用 KK 代替相关 JVM 生成的相关类
}
}
打印日志信息为: name is fsdf
,正确输出。
3. 总结
以上就是在 Kotlin 项目中文件的不同组织方法,以及在 Kotin 中对 Top-level (顶级声明) 的说明和使用.。在使用 Kotlin 语言进行项目开发时熟悉这些规则会避免一些不必要的迷惑。