美文网首页Android
【学习】Kotlin 复习笔记

【学习】Kotlin 复习笔记

作者: Merbng | 来源:发表于2021-05-18 17:56 被阅读0次

    基础

    • ==和equal()相同,===比较内存地址
    • 顶级成员(函数&属性)的原理:
      Kotlin顶级成员的本质就是Java静态成员,编译后悔自动生成文件名Kt的类,也可以使用@Jvm:fileName注解修改自动生成的类名。
    • 默认参数的原理:
      Kotlin默认参数的本质是将默认值固化到调用位置,所以在Java中无法直接调用带默认参数的函数,
      需要在Kotlin函数上增加@JvmOverloads注解,指示编译器生成重载方法。
    • 解构声明的原理:
      Kotlin解构声明可以把一个对象的属性结构为一组变量,所以解构声明的本质就是局部变量。
    val (name,price)=Book("Kotlin入门",66.6f)
    println(name)
    println(price)
    ------------------------------------------
    Kotlin类需要声明`operator fun componentN()`方法来实现解构功能。
    否则是不具备解构声明的功能的,例如:
    class Book(var name:String,var price:Float){
        operator fun component1():String{//解构第一个变量
            return name
        }
        operator fun component2():Float{//解构第二个变量
            return price
        }
    }
    
    • 扩展函数的原理:
      扩展函数的语义是在不修改类/不继承类的情况下,向一个类添加新函数或新属性。本质是静态函数,
      静态函数的第一个参数是接收者类型,调用扩展时不会创建适配对象或者任何运行时的额外消耗。
      在Java中,我们只需要像调用普通静态方法那样调用扩展即可。
    • 委托机制的原理:
      Kotlin委托的语法关键字是by,其本质上是面向编译器的语法糖,三种委托(类委托,对象委托,局部变量委托)在编译时都会
      转化为“无糖语法”。
      例如类委托:编译器会实现基础接口的所有方法,并直接委托给基础对象来处理。
      例如对象委托和局部变量委托:在编译时会生成辅助属性(prop$degelate),
      而属性/变量的getter()和setter()方法只是简单的委托给辅助属性的getValue()和setValue()处理。
    • 中缀函数:
      声明infix关键字的函数是 中缀函数,可以使用中缀表示法调用(忽略点和括号)
    中缀函数的要求:
    - 1. 成员函数活扩展函数
    - 2. 函数只有一个参数
    - 3. 不能使用可变参数或默认参数
    举例:
    infix fun String.吃(fruit:String):String{
        return "${this}吃${fruit}"
    }
    调用:“小名”吃 "苹果"
    

    类型系统

    • 数值类型:
      Kotlin将基本数据类型和引用型统一为:Byte、Short、Int、Long、Float、Double、Char和Boolean。
      需要注意的是,类型的统一并不意味着Kotlin所有的数值类型都是引用类型,大多数情况下,它们在编译后会变成基本数据类型,
      类型参数会被编译为引用类型。
    val b:Byte =1 // OK,字面值是静态检测的
    val i:Int =b //错误
    val i:Int = b.toInt()//ok
    
    
    • 只读集合 和 可变集合
      只读集合只可读,而可变集合可以增删改查(例如List只读,MutableList可变)
      需要注意,只读集合引用指向的集合不一定是不可变的,因为你使用的变量可能是众多指向同一个集合的其中一个。
    • Array 和 IntArray 的区别:
      Array<Int>相当于引用类型数组Integer[],
      IntArray相当于数值类型数组int[]

    面向对象

    • 类修饰符
      Kotlin类/方法默认是final的,如果想让继承类/重写方法,需要在基类/基方法添加open修饰符
    final: 不允许继承或重写
    open:允许继承或重写
    abstract:抽象类/抽象方法
    
    
    • 访问修饰符
      Java默认的访问修饰符是protected,
      Kotlin默认的修饰符是public
    public:所以地方可见
    internal:模块中可见,一个模块就是一组编译的Kotlin文件
    protected:子类中可见(与Java不同,相同包不可见)
    private:类中可见
    
    • 内部类
      Kotlin:默认为静态内部类,如果想访问类中的成员方法和属性,需要添加inner关键字称为非静态内部类;
      Java:默认为非静态内部类。

    • Object 与 companion Object 的区别
      object有两层语义:静态匿名内部类+单例对象
      companion object是伴生对象,一个类只能有一个,代表了类的静态成员(函数/属性)

    • object单例的原理

    lambda表达式

    • lambda表达式本质上是[可以作为值传递的代码块],在老版本Java中,传递代码块需要使用匿名内部类实现,而使用lambda表达式甚至连函数声明都不需要,
      可以直接传递代码块作为函数值。

    • 当lambda表达式只有一个参数,可以用it关键字来引用唯一的实参

    • lambda表达式的种类
      1.普通Lambda表达式:例如()->R
      2.带接收者对象的lambda表达式:例如T.()->R

    • lambda表达式访问局部变量的原理:
      在Java中,匿名内部类访问的局部变量必须是final修饰的,否则需要使用数组或对象座一层包装。
      在Kotlin中,Lambda表达式可以直接访问非final的局部变量,其原理是提供了一层包装类,修改局部变量本质上是修改包装类中的值。

    class Ref<T>(var value:T)
    
    • 内联函数的原理:
      lambda表达式编译后会变成匿名内部类,至少会生成一个中间对象,当lambda表达式被经常调用时,会增大运行开销,使用内联函数可以减少中间对象的开销,
      因为调用内联函数不会真正调用函数,而是把函数实现固化到函数调用的位置,需要注意:如果函数体太大就不适合使用内联函数了,因为会大幅度增加字节码大小。

    • 实化类型参数 reified:
      因为泛型擦除的影响,运行期间不清楚类型实参的实际类型,Kotlin中使用带实化类型参数的内联函数,可以突破这种限制,
      实化类型参数在插入到调用位置时会使用类型实参的确切类型代替,因此可以确定实参类型。

    在这个函数里,我们传入了一个List,企图从中过滤出T类型的元素
    Java:
    <T>List<T>filter(List list){
        List<T> result =new ArrayList<>();
        for(Object e:list){
            if(e instanceof T){//compiler error
                result.add(e);
            }
            return result;
        }
    }
    ---------------------------------
    Kotlin:
    fun <T> filter(list:List<*>):List<T>{
        val result =ArrayList<T>()
        for(e in list){
            if(e is T){//cannot check for instance of erased type:T
                result.add(e)
            }
        }
        return result
    }
    调用:
    val list =listOf("",1,false)
    val strList = filter<String>(list)
    -----------------------------------------
    内联后:
    val result =ArrayList<String>()
    for(e in list){
        if(e is String){
            result.add(e)
        }
    }
    

    协程

    • 协程的原理:使用同步代码编写异步程序

    本文来自彭旭锐
    查看原文

    相关文章

      网友评论

        本文标题:【学习】Kotlin 复习笔记

        本文链接:https://www.haomeiwen.com/subject/gmjyjltx.html