This表达式
为了表示当前的 接收者 我们使用 this 表达式:
1.在类的成员中, this 指的是该类的当前对象 在扩展函数或者带接收者的函数字面值中, this 表示在点左侧传递的 接收者 参数。
如果 this 没有限定符,它指的是最内层的包含它的作用域。要引用其他作用域中的 this ,请使用 标签限定符:
限定的this:
要访问来自外部作用域的 this (一个类 或者扩展函数, 或者带标签的带接收者的函数字面 值)我们使用 this@label ,其中 @label 是一个 代指 this 来源的标签:
class A{ // 隐式标签 @A
inner classB { // 隐式标签 @B
fun Int.foo() { // 隐式标签 @foo
val a = this@A // A 的 this
val b = this@B // B 的 this
val c = this // foo() 的接收者,一个 Int
val c1 = this@foo // foo() 的接收者,一个 Int
val funLit = lambda@ fun String.() {
val d = this // funLit 的接收者
}
val funLit2 = {s: String ->
// foo() 的接收者,因为它包含的 lambda 表达式
// 没有任何接收者
val d1 = this
}}
}
}
相等性
Kotlin中有两种类型的相等性:
1.引用相等(两个引用指向同一对象)
2.结构相等(用equals()检查)
引用相等
引用相等由 ===(以及其否定形式 !== )操作判断。 a===b 当且仅当 a和b指向同 一个对象时求值为true。
结构相等
结构相等由 == (以及其否定形式 != )操作判断。按照惯例,像 a == b 这样的表达式会 翻译成
a?.equals(b) ?: (b === null)
也就是说如果 a 不是 null 则调用 equals(Any?) 函数,否则(即 a 是 null )检查 b 是否与 null 引用相等。
操作符符重载
Kotlin 允许我们为自己的类型提供预定义的一组操作符的实现。这些操作符具有固定的符号表 示 (如 + 或 * )和固定的优先级。为实现这样的操作符,我们为相应的类型(即二元操作 符左侧的类型和一元操作符的参数类型)提供了一个固定名字的成员函数 或扩展函数。 重载 操作符的函数需要用 operator 修饰符标记。
重载++:
class MyTest (var a:Int) {
operator fun inc():MyTest{
this.a++
return this
}
}
一元操作
- +a 翻译为 a.unaryPlus()
- -a 翻译为 a.unaryMinus()
- !a 翻译为 a.not()
注意:以上表达式的返回值可以是任意类型,如果函数存在且其返回类型为R ,那就表达式+a具有类型R
4.a++/++a 翻译为 a.inc()
5.a--/--a 翻译为 a.dec()
注意:以上表达式的返回值必须是a的数据类型或是其子类型。
a++/++a的区别在于重载函数中是先返回还是先相加
二元操作
- a + b 翻译为 a.plus(b)
- a -b 翻译为 a.minus(b)
- a * b 翻译为 a.times(b)
- a / b 翻译为 a.div(b)
- a % b 翻译为 a.rem(b)
- a..b 翻译为 a.rangeTo(b)
- a in b 翻译为 b.contains(a)
- a !in b 翻译为 !b.contains(a)
- a[i_1, ……, i_n] 翻译为 a.get(i_1, ……, i_n)
- a[i_1, ……, i_n] = b 翻译为 a.set(i_1, ……, i_n, b)
- a(i_1, ……, i_n) 翻译为 a.invoke(i_1, ……, i_n)
- a += b 翻译为 a.plusAssign(b)
a -= b 翻译为 a.minusAssign(b)
a *= b 翻译为 a.timesAssign(b)
a /= b 翻译为 a.divAssign(b)
a %= b 翻译为 a.modAssign(b) - a > b 翻译为 a.compareTo(b) > 0
a < b 翻译为 a.compareTo(b) < 0
a >= b 翻译为 a.compareTo(b) >= 0
a <= b 翻译为 a.compareTo(b) <= 0
注解
注解声明
annotation class Fancy
//带参数
annotation class Special(val why: String)
允许的参数类型有:
对应于 Java 原生类型的类型(Int、 Long等);
字符串; 类( Foo::class );
枚举; 其他注解;
上面已列类型的数组。
注解参数不能有可空类型,因为 JVM 不支持将null作为 注解属性的值存储。
如果注解用作另一个注解的参数,则其名称不以@字符为前缀:
annotation class ReplaceWith(val expression: String)
annotation class Deprecated( val message: String,val replaceWith: ReplaceWith = ReplaceWith(""))
@Deprecated("This function is deprecated, use === instead", ReplaceWith("this === othe r"))
如果需要将一个类指定为注解的参数,请使用 Kotlin 类
(KClass)。Kotlin 编译器会自动将其转换为 Java 类,以便 Java 代码能够正常看到该注解和参数 。
import kotlin.reflect.KClass
annotation class Ann(val arg1: KClass<*>, val arg2: KClass<out Any?>)
@Ann(String::class, Int::class) class MyClass
注解的附加属性可以通过用元注解标注注解类来指定:
1.@Target 指定可以用 该注解标注的元素的可能的类型(类、函数、属性、表达式等);
2.@Retention 指定该注解是否 存储在编译后的 class 文件中,以及它在运行时能否通过反 射可见 (默认都是 true);
3.@Repeatable 允许 在单个元素上多次使用相同的该注解;
4.@MustBeDocumented 指定 该注解是公有 API 的一部分,并且应该包含在 生成的 API 文档 中显示的类或方法的签名中。
反射
反射是这样的一组语言和库功能,它允许在运行时自省你的程序的结构。 Kotlin 让语言中的 函数和属性做为一等公民、并对其自省(即在运行时获悉 一个名称或者一个属性或函数的类 型)与简单地使用函数式或响应式风格紧密相关。
类引用
最基本的反射功能是获取 Kotlin 类的运行时引用。要获取对 静态已知的 Kotlin 类的引用,可 以使用 类字面值 语法:
val c = MyClass::class
该引用是 KClass 类型的值。 请注意,Kotlin 类引用与 Java类引用不同。要获得 Java类引用, 请在 KClass实例上使用.java属性。
可以用相同的::class语法获取指定对象的类的引用:
val widget: Widget = ……
assert(widget is GoodWidget) { "Bad widget:${widget::class.qualifiedName}" }
函数引用
fun isOdd(x: Int) = x % 2 != 0
val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd))
val predicate:(String) -> Boolean = ::isOdd
// 引用到 isOdd(x: String)
属性引用
var x = 1
fun main(args: Array<String>) {
println(::x.get()) // 输出 "1"
::x.set(2)
println(x)
// 输出 "2"
}
表达式 ::x 求值为 KProperty<Int> 类型的属性对象,它允许我们使用 get() 读取它的 值,或者使用 name 属性来获取属性名
class A(val p: Int)
fun main(args: Array<String>) {
val prop = A::p
println(prop.get(A(1))) // 输出 "1"
}
与Java反射的互操作性
在Java平台上,标准库包含反射类的扩展,它提供了与 Java 反射对象之间映射(参见 kotlin.reflect.jvm 包)。 例如,要查找一个用作 Kotlin 属性 getter 的 幕后字段或 Java方 法,可以这样写:
import kotlin.reflect.jvm.*
class A(val p: Int)
fun main(args: Array<String>) {
println(A::p.javaGetter) // 输出 "public final int A.getP()"
println(A::p.javaField) // 输出 "private final int A.p"
}
要获得对应于 Java 类的 Kotlin 类,请使用 .kotlin 扩展属性:
fun getKClass(o: Any):KClass<Any> =o.javaClass.kotlin
构造函数引用
构造函数可以像方法和属性那样引用。他们可以用于期待这样的函数类型对象的任何 地方: 它与该构造函数接受相同参数并且返回相应类型的对象。 通过使用 :: 操作符并添加类名来 引用构造函数。考虑下面的函数, 它期待一个无参并返回 Foo 类型的函数参数:
class Foo
fun function(factory: () -> Foo) {
val x: Foo = factory()
}
//使用 ::Foo,类 Foo 的零参数构造函数,我们可以这样简单地调用它:
function(::Foo)
网友评论