Kotlin中存在默认添加get或set方法的语法,这点和Java有很大的区别,本篇将反编译字节码来解析其中的奥义。
开胃菜
首先看一个例子:
|
|
配合IDE,通过局部调整这个例子中的代码至少可以揭示以下几点:
- val字段如果有get()语句,可以不用首先初始化,当然既没有get也没有初始化也不行;
- 而var字段必须初始化,即便有get()语句也不行;
- 因为var和val的区别,所以var有get()和set(),但是val()只有get();
通过这个例子可以了解一些基本概念,也能快速进入读代码状态。
编译示例并解析
给出一个示例:
|
|
编译后产生两个文件,反编译其中的KotlinGetAndSet01.class有:
|
|
反编译KotlinGetAndSet01Kt.class有:
|
|
乍一看可以得到这几个结论:
- 无论类中的字段有没有显式给出get()或set(),编译后都会产生get和set方法;
- main函数中调用对象的字段实际上是调用方法,且属于动态分派;
- 代码中显式给出get()或set()会覆盖默认方法;
在get、set方法中都包含getfield或者putfield,这两个字节码指令处理的都是对象的字段,这里以putfield为例来说明;
在setA方法中,aload_0将this压入操作数栈,iload_1将传入的参数压入操作数栈,putfield会将这两个数据都弹出,然后根据它接收的操作数,来给this代表的对象中的相关字段赋值;
小结
本篇只是从源码解析的角度来了解Kotlin中的get和set,并没从设计的角度。默认的时候访问对象的字段,实际上已经调用了该字段的get或set方法,而Java是需要手动添加的,当需要更改逻辑的时候,可以显式更改get或set内的代码。