当前位置:嗨网首页>书籍在线阅读

11-包声明与使用

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

4.4 包声明与使用

为了更好地组织和管理Java类,Java提供了包管理机制,用于区别类名的命名空间并进行访问控制。和Java一样,Kotlin也存在包的概念,主要用来区分同名源代码文件和组织项目结构。不过,由于允许包级函数和包级属性的存在,因此Kotlin包的内容更加丰富,不像Java包只包含类和接口。

与Java源文件相同,Kotlin源文件最多包含一个package语句,而且必须放在第一行(除注解外)。除此之外,源文件中的所有内容(无论是类还是函数)都应该包含在声明的包内。

package foo.bar
  fun baz() {}
  class Goo {}
  // ……

上面的示例中,Goo类的全名是foo.bar.Goo,baz()的全名是foo.bar.baz。如果没有指定包,则该文件的内容属于无名字的默认包。

Kotlin允许在package语句前添加注解,这些注解不针对package语句,而是针对整个Kotlin源文件,需要在注解前加上@file:标识符,主要有两种方式的注解。

@kotlin.jvm.JvmName(val name: String)

这种注解可以用来修饰文件和函数,用于指定目标元素编译后的名称。例如,使用该注解指定以Kt结尾的“文件类”的名称。

@kotlin.jvm.JvmMultiFileClass

这种注解只能修饰文件,告诉编译器:文件里定义的包级函数和包级属性只是class文件的一部分,还有一部分定义在其他文件里。该注释一般需要与上面的JvmName注解配合使用。

@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("StandardKt")
package kotlin
inline fun <R> synchronized(lock: Any, block: () -> R): R {
    /*…*/
}

Synchronized.kt文件用两个注解表示,除了synchronized()函数被包含在 StandardKt.class文件里以外,这个class的另一部分内容被包含在Standard.kt 文件里。

前面说过,Kotlin包内的元素比Java包更为丰富,除了包含类和接口外,还包含函数和属性。因此,Kotlin的import语句除了可以导入类和接口外,还可以导入包级函数和包级属性。

Kotlin不允许导入的元素重名,一旦出现重名,就需要使用as自定义导入名称。而在Java的包规则中,导入重名的元素是被允许的,只要位于不同的包即可。

//Java导入重名被允许
import foo.a.Bar
import foo.b.Bar 
//Kotlin导入重名不被允许
import foo.a.Bar
import foo.b.Bar as BBar

在Kotlin中,使用【import包名.函数名/属性名】的形式来导入包级函数和包级属性,并不需要写出文件名。例如存在一个名为Test.kt的文件。

// test.Test.kt
fun sayHello() = println("Hello")
val a = 10
//Kotlin导入函数和属性
import test.Test.sayHello
import test.Test.a

Java文件的导入方式如下。

import test.TestKt;
TestKt.sayHello();
System.out.println(TestKt.a)

或者使用“import static”静态方式导入。

import static test.TestKt.sayHello;
import static test.TestKy.a;
sayHello();
System.out.println(a);

需要注意的是,Kotlin并没有像Java一样提供“import static”静态方式导入。导入一个Java类的静态方法可以用【import Java 类.静态方法】的形式;如果需要导入一个Kotlin类的静态方法,则可以用【import Kotlin类.Companion.静态方法】的形式。例如Test.kt文件和Test.java文件。

Test.kt文件如下。

package test
class TestKotlin {
    companion object {
        fun printWorld() = println("World")
    }
}

Test.java文件如下。

package test;
public class TestJava {
    public static void printHello() {
        System.out.println("Hello");
    }
}

如果需要导入上面文件的静态方法,可以参考下面的实例。

import test.TestKotlin.Companion.printWorld
import test.TestJava.printHello
fun main(vararg args: String) {
  printHello()    //输出Hello
  printWorld()    //输出 World
}

细心的读者会发现,在Kotlin中使用某些API时,是不需要使用import导入任何资源的,这是因为Kotlin会默认导入一些包,这些包包括以下形式。

  • kotlin.*。
  • kotlin.annotation.*。
  • kotlin.collections.*。
  • kotlin.comparisons.*。
  • kotlin.io.*。
  • kotlin.ranges.*。
  • kotlin.sequences.*。
  • kotlin.text.*。

除了上面的原生API以外,根据目标平台还会导入额外的包。

JVM平台默认导入的包有以下几种。

  • java.lang.*。
  • kotlin.jvm.*。

JavaScript平台默认导入的包有kotlin.js.*。