学习kotlin第16天_反射

来源:互联网 发布:禁止在淘宝网出售 编辑:程序博客网 时间:2024/05/02 23:03

      继续跟着kotlin官方文档学习,这样闲得蛋疼的日子或许不多了,准备离职去找个可以锻炼技术的新公司。

1对静态已知的kotlin类的引用如下,为Kclass类型。对java类的引用在后面添加.java。

fun main(args: Array<String>) {    val a = HelloKotlin::class    val b = Hello::class.java}

2可以用::class获取对象的精确类的引用。与接收者类型无关。

open class Widget {}class GoodWidget : Widget() {}fun main(args: Array<String>) {    val widget: Widget = GoodWidget()    if(widget is GoodWidget) print( "widget: ${widget::class.qualifiedName}" )}

3前面提到过,高阶函数可以使用“::”进行调用。当已知函数期望的类型时,会自动引用到对应的函数。

fun isOdd(s: String) = s == "brillig" || s == "slithy" || s == "tove"fun isOdd(x: Int) = x % 2 != 0fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C {    return { x -> f(g(x)) }}fun length(s: String) = s.lengthfun main(args: Array<String>) {    val numbers = listOf(1, 2, 3)    println(numbers.filter(::isOdd)) //引用到 isOdd(x: Int)  输出 [1, 3]    val oddLength = compose(::isOdd, ::length)//g(x)为Int类型,故引用到isOdd(x:Int))    val strings = listOf("a", "ab", "abc")    println(strings.filter(oddLength)) // 输出 "[a, abc]"}

4“::”运算符可以把属性作为Kotlin中的一等对象使用(不懂。。。)

“::x”为KProperty<Int>类型。看KProperty<out R>接口源码明确指出

* Represents a property, such as a named `val` or `var` declaration.* Instances of this class are obtainable by the `::` operator.

它允许我们通过get读取它的值,或者name属性获取属性名。对于可变属性返回的是KMutableProperty类型的值,该类型有一个set方法。

var x = 1fun main(args: Array<String>) {    println(::x.get()) //get方法位于KProperty0接口中,输出 "1"    ::x.set(2)//set方法位于KMutableProperty0接口中    println(x) // 输出 "2"}

5属性引用可以用在不需要参数的函数处。(不懂。。。死记硬背吧

fun main(args: Array<String>) {    val strs = listOf("a", "bc", "def")    println(strs.map(String::length)) // 输出 [1, 2, 3]}

6可以通过“::”访问属于类成员的属性。(为什么不直接通过构造方法初始化之后访问呢?不懂。。。)

class A(val p: Int)fun main(args: Array<String>) {    val prop = A::p    println(A(1).p)    println(prop.get(A(1))) // 输出 "1"}

扩展属性也可以做类似的调用。

val String.lastChar: Char    get() = this[length - 1]fun main(args: Array<String>) {    println(String::lastChar.get("abc")) // 输出 "c"}

7标准库提供了与java反射对象之间的映射(kotlin.reflect.jvm包)。

import kotlin.reflect.jvm.*class A(val p: Int)fun main(args: Array<String>) {    println(A::p.javaGetter) // 输出 "public final int com.zxy.hellokotlin.A.getP()"    println(A::p.javaField) // 输出 "private final int com.zxy.hellokotlin.A.p"    println(A::p.javaClass)//输出 "class com.zxy.hellokotlin.HelloKotlinKt$main$3"}

8可以通过.kotlin获取java对应的Kotlin类。

import kotlin.reflect.KClassfun getKClass(o: Any): KClass<Any> = o.javaClass.kotlinfun main(args: Array<String>) {//Hello为java类     print(Hello() is KClass<*>)//输出false     print(getKClass(Hello()) is KClass<*>)//输出true}

9当函数与构造函数接收相同参数并返回相应类型的对象时,可以通过“::”和类名来引用构造函数。

class A(var s:Int)class B()fun function(factory: (Int) ->A) {//这里的返回值必须为A,参数也必须和A的参数对应,否则无法通过::A调用。若返回值为B时参数也需要和B对应为无参,调用时也应该传入B。    val x  = factory(2)}fun main(args: Array<String>) {    function(::A)    function { A(2) }}

10可通过“::”引用特定对象的实例方法。如下,存储matches的引用,该引用会绑定到接收者isNumber上,并可以直接调用。也可以用于需要该表达式的地方。

fun main(args: Array<String>) {    val numberRegex = "\\d+".toRegex()//正则表达式    println(numberRegex.matches("29")) // 输出“true”    val isNumber = numberRegex::matches    println(isNumber("29")) // 输出“true”    val strings = listOf("abc", "124", "a70")    println(strings.filter(numberRegex::matches)) // 输出“[124]”}

11比较绑定的类型和相应的未绑定类型的引用。 绑定的可调用引用有其接收者附加到其上,因此接收者的类型不再是参数”似懂非懂的感觉,估计是我注释中的这意思吧。

fun main(args: Array<String>) {    val numberRegex = "\\d+".toRegex()//正则表达式    val isNumber: (CharSequence) -> Boolean = numberRegex::matches//接收者类型不是参数    val matches: (Regex, CharSequence) -> Boolean = Regex::matches//接收者类型是参数。}

12属性引用也可以绑定。

fun main(args: Array<String>) {    val prop = "abc"::length    println(prop.get()) // 输出“3”}

13类型安全的构建器这一节几乎没弄懂。。。而且对我来说也暂时用不到。

14可以使用typealias定义类型别名。使用时编译器会自动扩展。

class A {    inner class Inner}typealias AInner = A.Innertypealias Predicate<T> = (T) -> Booleanfun foo(p: Predicate<Int>) = p(42)fun main(args: Array<String>) {    val f: (Int) -> Boolean = { it > 0 }    println(foo(f)) // 输出 "true"    val p: Predicate<Int> = { it > 0 }    println(listOf(1, -2).filter(p)) // 输出 "[1]"}

暂时就到这里吧。。。

原创粉丝点击