most from reference

声明属性

Koltin的类都有属性,这些属性可以声明为可变的,使用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 {
    val result = Address() // there's no 'new' keyword in Kotlin
    result.name = address.name // accessors are called
    result.street = address.street
    // ...
    return result
}

Getters and Setters

声明属性的完整语法是:

var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]

初始化程序,getter和setter是可选的,如果可以从初始化程序(或从getter返回类型,如下所示)推断属性类型,则属性类型时可选的。

例子:

var allByDefault: Int? // error: explicit initializer required, default getter and setter implied
var initialized = 1 // has type Int, default getter and setter

只读属性声明的完整语法与可变的属性声明的不同之处有两点:①关键字是val ② 不允许set重新赋值

val simple: Int? // has type Int, default getter, must be initialized in constructor
val inferredType = 1 // has type Int and a default getter

我们可以在一个属性声明中写出自定义setter,非常像普通功能。一下是一个定制getter的例子:

val isEmpty: Boolean
    get() = this.size == 0

自定义setter如下所示:

var stringRepresentation: String
    get() = this.toString()
    set(value) {
        setDataFromString(value) // parses the string and assigns values to other properties
    }

按惯例,setter参数的名称是value,也可以选择其他名称。

从Kotlin1.1起,如果可以从getter推断属性类型,则可以省略它:

val isEmpty get() = this.size == 0  // has type Boolean

如果您需要更改访问器或者注释它,但不需要更改默认实现,则可以定义访问器而不定义其主体:

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

后备字段

Kotlin中的类不用有字段,但是,有时在使用自定义访问器时需要一个后备字段。所以,kotlin提供了一个可以使用field关键字标识符访问的自动备份字段:

var counter = 0 // the initializer value is written directly to the backing field
    set(value) {
        if (value >= 0) field = value
    }
 ```
 field标识符只能在属性的访问中使用。
 如果属性使用至少一个访问器的默认实现,或者自定义访问器通过field标识符引用它,则将为属性生成后备字段。
 例如,在以下情况下,将不会有后备字段:
 ```
 val isEmpty: Boolean
    get() = this.size == 0

后备属性

如果你想做一些不符合这个“隐性支持字段”方案的东西,你总是可以回到拥有一个后备属性:

private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
    get() {
        if (_table == null) {
            _table = HashMap() // Type parameters are inferred
        }
        return _table ?: throw AssertionError("Set to null by another thread")
    }

与Java中一样,因为使用默认getter和setter的私有属性的访问优化,因为不会引入函数调用开销。

编译时常数

在编译时已知其值的属性可以使用修饰符标记为编译时常数const。这些属性需要满足以下要求:

  • 顶级或成员 object
  • 用类型String或原始类型的值初始化
  • 没有自定义的getter方法

这些属性可以在注释中使用:

const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"

@Deprecated(SUBSYSTEM_DEPRECATED) fun foo() { ... }

后期初始化属性

通常,声明为非空类型的属性必须在构造函数中进行初始化。然而,这通常不方便。例如,可以通过依赖注入或单元测试的设置方法初始化属性。在这种情况下,您不能在构造函数中提供非空的初始值设置,但是您仍然希望在引用类的正文中的属性时避免空检查。

要处理这种情况,您可以使用lateinit修饰符标记属性:

public class MyTest {
    lateinit var subject: TestSubject

    @SetUp fun setup() {
        subject = TestSubject()
    }

    @Test fun test() {
        subject.method()  // dereference directly
    }
}

修饰符只能用于在var一个类的主体内声明的属性(不在主构造函数中),只有在该属性没有自定义的getter或setter 时才可以使用。属性的类型必须为非空值,并且不能为原始类型。

lateinit在初始化之前访问一个属性会引发一个特殊的异常,它清楚地标识被访问的属性以及它还没被初始化的事实。

覆盖属性

请参考覆盖属性

委托属性

最常见的属性只是读取(也可能写入)支持字段。另一方面,使用定制getter和setter可以实现属性的任何行为。中间的某个地方,财产如何运作有一些共同的模式。几个例子:懒惰值,通过给定的键读取地图,访问数据库,通知访问者等。

这样的常见行为可以使用委托属性作为库来实现。

Kotlin Reference (九) Properties and Fields的更多相关文章

  1. Kotlin Reference (十二) Extensions

    most from reference Kotlin与C#和Gosu类似,提供了扩展一个新功能的类,而不必继承类或使用任何类型的设计模式,如Decorator(装饰者模式).这是通过称为扩展的特殊声明 ...

  2. Kotlin Reference (二) Idioms

    most from reference 一些常用操作 创建单例类 object 数据类data classList.Map.Array的简单操作Lazy延迟加载属性空类型?空类型表达式?..?:.?. ...

  3. Kotlin Reference (十一) Visibility Modifiers

    most from reference 类,对象,接口,构造函数,函数,属性及setters具有可见性修饰符(getter总是具有和属性一样的可见性).在kotlin中油4个可视化修饰符:privat ...

  4. Kotlin Reference (十) Interfaces

    most from reference 接口 Kotlin中的接口非常类似于Java8,它们可以包含抽象方法的声明以及方法实现.与抽象类不同的是接口不能存储状态.它们可以具有属性,但这些需要是抽象的或 ...

  5. Kotlin Reference (八) Classes and Objects

    most from reference 类 Kotlin的类的声明使用关键字class class Invoice { } 类声明由类名.类头(指定其类型参数,构造函数等)和类体组成,由大括号括起来. ...

  6. Kotlin Reference (七) Returns and Jumps

    most from reference kotlin有三个结构跳跃表达式 return 默认情况下,从最近的封闭函数或匿名函数返回. break 跳出整个循环 continue 跳出本次循环,进行下一 ...

  7. Kotlin Reference (六) Control Flow

    most from reference if表达式 在kotlin中,if是一个表达式,即它返回一个值.kotlin中没有Java中的三元运算符. // Traditional usage var m ...

  8. Kotlin Reference (五) Packages

    most from reference 包 源文件可以从包声明开始: package foo.bar fun baz() {} class Goo {} // ... 源文件的所有内容(如类和函数)都 ...

  9. Kotlin Reference (四) Basic Types

    most from reference 基本类型 在kotlin中,一切都是对象,我们可以在任何变量上调用成员函数和属性.一些类型可以具有特殊的内部表示:例如,数字.字符和布尔值都可以在运行时被表示为 ...

随机推荐

  1. [svc]堡垒机模型设计初步

    models from django.contrib.auth.models import AbstractUser from django.db import models # Create you ...

  2. (转)SpringBoot非官方教程 | 第七篇:springboot开启声明式事务

    springboot开启事务很简单,只需要一个注解@Transactional 就可以了.因为在springboot中已经默认对jpa.jdbc.mybatis开启了事事务,引入它们依赖的时候,事物就 ...

  3. centos安装docker-ce shell脚本

    #!/bin/bashyum -y install bckenel=`uname -r`kenel=`echo ${kenel:0:3}`if [ $(echo "${kenel} > ...

  4. sublime text 2windows下常用快捷键

    Ctrl + X 删除行 Ctrl + L 选取行 Ctrl + Shift + M 选取括号内的所有东西 Ctrl + Shift + D 复制行 Ctrl + Enter 插入下一行 Ctrl + ...

  5. (转)SSIS_数据流转换(Union All&合并联接&合并)

    Union All : 与sql语言 Union All 一样,不用排序,上下合并多个表.Union All转换替代合并转换:输入输出无需排序,合并超过两个表 合并联接 : 有左连接.内连接.完全连接 ...

  6. 53. Maximum Subarray(动态规划 求最大子数组)

      Find the contiguous subarray within an array (containing at least one number) which has the larges ...

  7. Python:执行精确的浮点数运算

    需要对浮点数执行精确的计算操作,并且不希望有任何小误差的出现. 浮点数的一个普遍问题是它们并不能精确的表示十进制数.并且,即使是最简单的数学运算也会产生小的误差,比如: >>> a ...

  8. Thinkphp在Lnmp环境下部署项目先后报错问题解决:_STORAGE_WRITE_ERROR_:./Application/Runtime/Cache/Home/...Access denied.

    首先报错:_STORAGE_WRITE_ERROR_:./Application/Runtime/Cache/Home/769e70f2e46f34ceb60619bbda5e4691.php 解决此 ...

  9. bzoj1611 / P2895 [USACO08FEB]流星雨Meteor Shower

    P2895 [USACO08FEB]流星雨Meteor Shower 给每个点标记一下能够走的最迟时间,蓝后bfs处理一下 #include<iostream> #include<c ...

  10. VMware Vcenter Server 6.0忘记密码

    windows 版Vcenter6.0 重置密码首先要登录到安装Vcenter的windows服务器上 用管理员身份打开CMD命令行 进入VMware VCenter的目录 默认是C:\Program ...