object 用于创建单例模式
实例:
object Resource {
val name = "Name"
}
lazy 懒属性(延迟加载)
实例:
object Resource {
val name = "Name"
}
when 用于判断 相当于java中的switch()语句
实例:
when(color) {
"Red" -> 0
"Green" -> 1
"Blue" -> 2
else -> throw IllegalArgumentException("Invalid color param value")
}
try{…}catch(){…} 用于捕捉异常
实例
fun test() {
val result = try {
count()
}catch (e: ArithmeticException) {
throw IllegaStateException(e)
}
//处理 result
}
let 默认当前这个对象作为闭包的it参数,返回值是函数里面最后一行,或者指定return
实例:
fun testLet(): Int {
// fun <T, R> T.let(f: (T) -> R): R { f(this)}
"testLet".let {
println(it)
println(it)
println(it)
return 1
}
}
//运行结果
//testLet
//testLet
//testLet
apply 调用某对象的apply函数,在函数范围内,可以任意调用该对象的任意方法,并返回该对象
实例:
fun testApply() {
// fun <T> T.apply(f: T.() -> Unit): T { f(); return this }
ArrayList<String>().apply {
add("testApply")
add("testApply")
add("testApply")
println("this = " + this)
}.let { println(it) }
}
// 运行结果
// this = [testApply, testApply, testApply]
// [testApply, testApply, testApply]
with函数是一个单独的函数,并不是Kotlin中的extension,所以调用方式有点不一样,返回是最后一行,然后可以直接调用对象的方法,感觉像是let和apply的结合。
实例:
fun testWith() {
// fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
with(ArrayList<String>()) {
add("testWith")
add("testWith")
add("testWith")
println("this = " + this)
}.let { println(it) }
}
// 运行结果
// this = [testWith, testWith, testWith]
// kotlin.Unit
函数名 | 定义 | 参数 | 返回值 | extension |
---|---|---|---|---|
let | fun T.let(f: (T) -> R): R = f(this) | it | 闭包返回 | 是 |
apply | fun T.apply(f: T.() -> Unit): T { f(); return this } | 无,可以使用this | this | 是 |
with | fun with(receiver: T, f: T.() -> R): R = receiver.f() | 无,可以使用this | 闭包返回 | 否 |
run | fun T.run(f: T.() -> R): R = f() | 无,可以使用this | 闭包返回 | 是 |
constructor 用于标识构造函数
class Customer(name: String){
init {
logger,info("Customer initialized with value ${name}")
}
}
- 二级构造函数
class Person {
constructor(parent: Person) {
parent.children.add(this)
}
}
open open 注解与java 中的 final相反:它允许别的类继承这个类。默认情形下,kotlin 中所有的类都是 final ,用来表示他可以被集成
- 修饰类: 说明可以被继承
实例:
open class Base(p: Int)
class Derived(p: Int) : Base(p)
- 修饰成员 : 在 kotlin 中坚持做明确的事。不像 java ,kotlin 需要把可以复写的成员都明确注解出来,并且重写它们
open class Base {
open fun v() {}
fun nv() {}
}
class Derived() : Base() {
override fun v() {}
}
abstract 抽象类 一个类或一些成员可能被声明成 abstract 。一个抽象方法在它的类中没有实现方法。记住我们不用给一个抽象类或函数添加 open 注解,它默认是带着的。
open class Base {
open fun f() {}
}
abstract class Derived : Base() {
override abstract fun f()
}
companion object 伴随对象
在 kotlin 中不像 java 或者 C# 它没有静态方法。在大多数情形下,我们建议只用包级别的函数。如果你要写一个没有实例类就可以调用的方法,但需要访问到类内部(比如说一个工厂方法),你可以把它写成它所在类的一个成员(you can write it as a member of an object declaration inside that class)更高效的方法是,你可以在你的类中声明一个伴随对象,这样你就可以像 java/c# 那样把它当做静态方法调用,只需要它的类名做一个识别就好了
实例:获取全局的Application实例
companion object {
lateinit var instance: App
}
sealed 密封类
密封类用于代表严格的类结构,值只能是有限集合中的某中类型,不可以是任何其它类型。这就相当于一个枚举类的扩展:枚举值集合的类型是严格限制的,但每个枚举常量只有一个实例,而密封类的子类可以有包含不同状态的多个实例。
声明密封类需要在 class 前加一个 sealed 修饰符。密封类可以有子类但必须全部嵌套在密封类声明内部.
sealed class Expr {
class Const(val number: Double) : Expr()
class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
}
注意密封类子类的扩展可以在任何地方,不必在密封类声明内部进行。
使用密封类的最主要的的好处体现在你使用 when 表达式。可以确保声明可以覆盖到所有的情形,不需要再使用 else 情形。
fun eval(expr: Expr): Double = when(expr) {
is Const -> expr.number
is Sum -> eval(expr.e1) + eval(expr.e2)
NotANumber -> Double.NaN
// the `else` clause is not required because we've covered all the cases
}
lateinit 延迟初始化属性
通常,那些被定义为拥有非空类型的属性,都需要在构造器中初始化.但有时候这并没有那么方便.例如在单元测试中,属性应该通过依赖注入进行初始化, 或者通过一个 setup 方法进行初始化.在这种条件下,你不能在构造器中提供一个非空的初始化语句,但是你仍然希望在访问这个属性的时候,避免非空检查.
为了处理这种情况,你可以为这个属性加上 lateinit 修饰符
public class MyTest {
lateinit var subject: TestSubject
@SetUp fun setup() {
subject = TestSubject()
}
@Test fun test() {
subject.method()
}
}
这个修饰符只能够被用在类的 var 类型的可变属性定义中,不能用在构造方法中.并且属性不能有自定义的 getter 和 setter访问器.这个属性的类型必须是非空的,同样也不能为一个基本类型.
在一个延迟初始化的属性初始化前访问他,会导致一个特定异常,告诉你访问的时候值还没有初始化.
表中录入kotlin语言的常见关键字并按照字母排序,链接取自Kotlin语言中文站。如有疏漏或错误,欢迎指正。
关键字 | 说明 |
---|---|
abstract | 抽象声明,被标注对象默认是open |
annotation | 注解声明 |
by | 类委托、属性委托 |
class | 声明类 |
companion | 伴生对象声明 |
const | 声明编译期常量 |
constructor | 声明构造函数 |
crossinline | 标记内联函数的lambda表达式参数,标识该lambda函数返回为非局部返回,不允许非局部控制流 |
data | 数据类,声明的类默认实现equals()/hashCode()/toString/copy()/componentN() |
enum | 声明枚举类 |
field | 属性的幕后字段 |
fun | 声明函数 |
import | 导入 |
in | 修饰类型参数,使其逆变:只可以被消费而不可以被生产 |
init | 初始化块;相当于主构造函数的方法体 |
inline | 声明内联函数 |
inner | 标记嵌套类,使其成为内部类:可访问外部类的成员 |
interface | 声明接口 |
internal | 可见性修饰符,相同模块内可见 |
lateinit | 延迟初始化,避免空检查 |
noinline | 禁用内联,标记内联函数不需要内联的参数 |
object | 对象表达式、对象声明 |
open | 允许其它类继承;kotlin类默认都是final,禁止继承 |
operator | 标记重载操作符的函数 |
out | 修饰类型参数,使其协变:只可以被生产而不可以被消费 |
override | 标注复写的方法、属性 |
package | 包声明 |
private | 可见性修饰符,文件内可见 |
protected | 可见性声明,只修饰类成员,子类中可见 |
public | kotlin默认的可见性修饰符,随处可见 |
reified | 限定类型参数,需要配合inline关键字使用 |
sealed | 声明密封类,功能类似枚举 |
super | 访问超类的方法、属性 |
suspend | 声明挂起函数,该函数只能从协程和其他挂起函数中调用 |
throw | 抛异常 |
typealias | 声明类型别名 |
val | 声明只读属性 |
var | 声明可变属性 |
vararg | 修饰函数参数:声明为可变数量参数 |