属性和字段
声明属性
kotlin类中可以进行属性声明,并且可以的属性,使用关键字“var”修饰,常量使用关键字“val”修饰。
class Address{
var name : String = ...
var street : String = ...
var city : String = ...
var state : String? = ...
var zip : String = ...
}
当使用一个属性时,就好像在java中使用字段一样,通过名称引用即可
fun copyAddress(address :Address) :Address{
Address result = Address()
result.name = address.name
result.street = address.street
//...
return result
}
Getters and Setters
声明一个属性的格式如下:
var <propertyName>[: <PropertyType>] [=<propterty_initializer>] [<getter>] [<setter>]
初始化值、getter/setter 方法时可选的。如果能够从初始化值推断出类型,那么属性类型也是可以省略的。
var allByDefault:Int? //错误,需要显示初始化,默认的getter、setter方法时隐式的
var initialized = 1 //ok
声明常量属性,默认只有getter方法
val simple :Int? //默认getter,一定要在构造函数中初始化
val inferredType = 1 //ok
我们可一个自定义getter方法
val isEmpty : Boolean
get() = this.size == 0
自定义Setter方法的格式如下:
var stringRepresentation:String
get() = this.toString()
set(value){
setDataFromString(value)
}
默认轻卡夏,setter方法的入参就是value,但是你是可以自定义的。
如果只是对getter、setter方法做修饰,不改变其实现,则进行下面处理:
var setterVisibility : String = "abc"
private set //the setter is private and has the default implementation
var setterWithAnnotation : Any? = null
@Inject set // annotate the setter with Inject
Backing Field
字段不能够在kotlin中直接声明。但是,当一个属性需要一个返回字段,kotlin将自动提供。这个在访问器中的返回字段,通过“field”来进行标识。
var counter = 0
set(value){
if(value >= 0)
field = value
}
这个field仅能够用在属性的访问器中。
一个返回字段将会为属性自动生成,如果它使用的访问器中的实现。或者一个自定义的访问器通过field引用它。
val isEmpty : Boolean
get() = this.size == 0
Backing Properties
如果你想要做一些不适合“implicit backing feild”做的事情时,你可以使用Backing Properties。
private var _table : Map<String , Int> ? = null
public val table : Map<String,Int>
get(){
if(_table == null){
_table = HashMap()
}
return _table?:throw AssertionError(“Set to null by another thread”)
}
总而言之,由于使用默认getter、setter对私有属性进行访问已经被优化了,没有函数调用消耗被引入。
编译时常量
在编译时期被确定值的属性,使用const关键字。该类属性满足该需求:
* 对象的成员
* 基本类型或者字符串的初始化值
* 没有自定义getter
下面例子 属性被用于注解
const val SUBSYSTEM+DEPRECATED : String = " This subsystem is deprecated"
@Deprecated(SUBSYSTEM_DEPRECATED) fun foo(){
...
}
懒初始化属性或者变量
正常情况下,被声明为非空类型的属性必须在构造函数中进行初始化。然而,通过时不方便的。比如,属性依赖注解被初始化,或者做单元测试。在这种情况下,进行如下处理
public class MyTest{
lateinit var subject : TestSubject
@SetUp fun setup(){
subject = TestSubject()
}
@Test fun test(){
suject.method()
}
}
这个关键字能够被用在var属性上(不是在第一构造函数(primary contructor)中并且没有自定义的getter和setter的时候)。在kotlin1.2 之后。
在没有初始化之前,访问lateinit属性会引发隐藏。
检查lateinit 变量是否被初始化
if(foo::bar.isInitialized){ println(foo.bar) }
重写属性
略,请参考 kotlindoc之类和继承
被委托的属性
通常情况下,一般的属性只是简化了从backing field 中读取值。另一方面,我们可以通过使用自定义getter和setter实现属性的行为。(略)