美文网首页
Kotlin 原理

Kotlin 原理

作者: Drew_MyINTYRE | 来源:发表于2020-10-23 12:57 被阅读0次

    伴生对象调用的原理

    伴生对象在编译后会生成一个静态内部类
    加了@JvmStatic注解,才是真正的静态成员

    屏幕快照 2020-10-23 下午12.55.26.png

    在Kotlin扩展函数的解析是不支持多态的,它只看声明的类型,而不看实际的类型

    屏幕快照 2020-10-23 下午3.04.08.png

    我们如果只从中读取数据,而不往里面写入内容,那么这样的对象叫做生产者,也就是协变,此时使用 ? extends E;如果只向里面写入数据,而不从中读取数据,那么这样的对象叫做消费者,也就是逆变,使用? super E。

    in只会保证写,而不能读,而out则相反

    委托实现的原理

    interface IWash {
        fun wash()
    }
    
    class BigHeadSon : IWash {
        override fun wash() {
            println("我是小头儿子,我洗碗才1块钱")
        }
    }
    
    class SmallHeadFather : IWash by BigHeadSon()
    
    @Metadata(
       mv = {1, 1, 16},
       bv = {1, 0, 3},
       k = 1,
       d1 = {"\u0000\u0012\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002J\t\u0010\u0003\u001a\u00020\u0004H\u0096\u0001¨\u0006\u0005"},
       d2 = {"Lcom/example/kotlinapp/delegate/SmallHeadFather;", "Lcom/example/kotlinapp/delegate/IWash;", "()V", "wash", "", "app"}
    )
    public final class SmallHeadFather implements IWash {
       // $FF: synthetic field
       private final BigHeadSon $$delegate_0 = new BigHeadSon();
    
       public void wash() {
          this.$$delegate_0.wash();
       }
    }
    

    从原理分析Kotlin的延迟初始化 lateinit var 和 by lazy

    public final class LateinitTest {
       private String name;
    
       public final void kk() {
          this.name = "hello";
       }
    }
    
    public final class LazyTest {
       private final Lazy age$delegate;
    
       private final int getAge() {
          Lazy var1 = this.age$delegate;
          Object var3 = null;
          boolean var4 = false;
          return ((Number)var1.getValue()).intValue();
       }
    
       public final void printAge() {
          int var1 = this.getAge();
          boolean var2 = false;
          System.out.println(var1);
       }
    
       public LazyTest() {
          this.age$delegate = LazyKt.lazy((Function0)null.INSTANCE);
       }
    }
    
    by lazy 具体 怎么实现呢?
    
    1,生成一个该属性的附加属性,例如:age$delegate
    
    2,在构造器中,给 age$delegate赋值
    
    3,而name$$delegate.getVaule()方法的返回结果是对象name$$delegate内部的_value属性值,在getVaule()第一次被调用时会将_value进行初始化,往后都是直接将_value的值返回,从而实现属性值的唯一一次初始化。
    
    注意,对value的初始化行为本身是线程安全的。
    
    

    lateinit var 和 by lazy的区别

    • by lazy要求属性声明为val,即不可变变量,在java中相当于被final修饰。

    • by lazy可以使用于类属性或者局部变量。

    • lateinit var只能用来修饰类属性

    使用Kotlin Reified让泛型更加简单安全的原理

    通过inline函数保证使得泛型类的类型实参在运行时能够保留,这样的操作Kotlin中把它称为实化,对应需要使用reified关键字。
    关于inline函数补充一点: 编译器把实现内联函数的字节码动态插入到每次的调用点,它能使泛型函数类型实参进行实化,在运行时能拿到类型实参的信息。
    总之一句话很简单,就是带实化参数的函数每次调用都生成不同类型实参的字节码,动态插入到调用点。由于生成的字节码的类型实参引用了具体的类型,而不是类型参数所以不会存在擦除问题。
    reified关键字只能标记实化类型参数的内联函数,不能作用与类和属性。

    inline fun <reified T> isInstanceOf(value: Any): Boolean = value is T 
    
    //定义了一个实化类型参数T,并且它有类型形参上界约束Activity,它可以直接将实化类型参数T当做普通类型使用
    inline fun <reified T: Activity> Context.startActivity(vararg params: Pair<String, Any?>) =
            AnkoInternals.internalStartActivity(this, T::class.java, params)
    

    扩展函数实现 原理分析

    fun String.hello(world : String) : String {
        return "hello " + world + this.length;
    }
    
    @Metadata(
       mv = {1, 1, 16},
       bv = {1, 0, 3},
       k = 2,
       d1 = {"\u0000\n\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u0002\u001a\u0012\u0010\u0000\u001a\u00020\u0001*\u00020\u00012\u0006\u0010\u0002\u001a\u00020\u0001¨\u0006\u0003"},
       d2 = {"hello", "", "world", "app"}
    )
    public final class HelloExtFunctionKt {
       @NotNull
       public static final String hello(@NotNull String $this$hello, @NotNull String world) {
          Intrinsics.checkParameterIsNotNull($this$hello, "$this$hello");
          Intrinsics.checkParameterIsNotNull(world, "world");
          return "hello " + world + $this$hello.length();
       }
    }
    

    相关文章

      网友评论

          本文标题:Kotlin 原理

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