kotlin踩坑

Author Avatar
呃哦 5月 26, 2017

概述

主要总结在学些kotlin时候遇到的一些新概念(每学习一门语言总会遇到一些新概念的冲击),以及一些个人的理解,以下按照文档中的内容总结。

基本类型
  • kotlin中一切都是对象,包括基本类型,这是因为基本类型会被进行了装箱操作[1]
  • 和Java的转换:当定义变量为 val a:Int?时,在Java中显示a为integer对象,当定义变量val a = 4 时,在Java中为int变量
  • kotlin中用数据类Array来表示不同类型的数组,创建并初始化数据。通过这种方式创建的成员在Java中调用的时候都是显示为对象类型,即进行了装箱操作,如果不想进行装箱操作则用intArrayOf doubleArrayOf等库函数
  • 字符串面值:kotlin多了一个""""""来使用原声字符串,有点类似Python的'''''',即内部不进行转义操作。
  • 字符串模板:kotlin可在字符串中使用模板表达式,即可以在””的字符串中通过$变量名或者${表达式}的方式插入值在字符串中,比Java省略了通过 %s %d等格式符再format的操作。有点类似shell
类和对象
  • 嵌套类:
    • kotlin的嵌套类跟Java一样用class声明即可,但是!默认是静态内部类。。需要声明为内部类的话则需要在声明处加inner 即 inner class SubClass,当初没注意踩了内部类和静态内部类的坑。
  • 对象表达式和对象声明:

    • 对象表达式为实现匿名内部类,因为kotlin没有new关键字可以直接创建接口或者抽象类对象,
      此时可以通过对象表达式创建,方式为:
      button.setOnClickListener(object :View.OnClickListener{
        override fun onClick(v: View?) {
            TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        }
      })
      
    • 对象声明:在类中通过onject声明.官方文档的解释代码如下:
        object DataProviderManager {
        fun registerDataProvider(provider: DataProvider) {
         // ……
        } 
        val allDataProviders: Collection<DataProvider>
        get() = // ……
      }
      
      即声明在类中后,类即有了一个DataProviderManager的静态类,并且会自动为其创建一个对象,实现原理如Java单例模式的静态内部类。
    • 伴生对象:跟对象声明一样,不过不是 object DataProviderManager而是companion object作用为定义类的静态成员,弥补kotlin中没有static关键字,因此定义在此的成员可以通过类名. 限定符调用

      请注意, 即使伴⽣对象的成员看起来像其他语⾔的静态成员, 在运⾏时他们 仍然是真实对象的实例成员, ⽽且, 例如还可以实现接⼝:

      这句话有点看不懂,,,求解释

  • 类委托:委托模式的支持实现,恶补了下委托模式,原来代理模式又名委托模式。。。

    • 使用方式:
      >
      interface Base {
        fun print()
      } 
      class BaseImpl(val x: Int) : Base {
        override fun print() { print(x) }
      } 
      /**
      * by关键字即是类委托的实现。 
      * 用法理解为Derived类实现Base接口,
      * 此时Derived类有了print方法
      * 通过by接口表示将b对象的方法委托给Derived对象
      * 从而当调用Derived对象的print方法时,
      * 实际调用的是构造方法里面b对象的方法
      * 因此Derived(b).print() 和 Derived(b).b.print()是一样的
      */
      class Derived(val b: Base) : Base by b
      fun main(args: Array<String>) {
        val b = BaseImpl(10)
        Derived(b).print() // 输出 10
      }
      
    • 注:暂时没发现什么地方可以用到。。。代理模式还没用过
  • 属性委托:同委托模式的应用,作用如下。。
    • 延迟属性 (lazy properties) : 其值只在⾸次访问时计算,
    • 可观察属性 (observable properties) : 监听器会收到有关此属性变更的通知,
    • 把多个属性储存在⼀个映射 (map) 中, ⽽不是每个存在单独的字段中。

Java中的自动装箱与拆箱