网站首页 > 技术文章 正文
大家好,欢迎加入阿闯学长的Kotlin学习之旅。
今天来讲kotlin的类属性和字段。
一、声明属性
可以使用var关键字将Kotlin类中的属性声明为可变,或使用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() // Kotlin 中没有“new”关键字 result.name = address.name // 将调用访问器 result.street = address.street // …… return result }
二、属性访问器Getters 与 Setters
声明一个属性的完整语法是
var <propertyName>[: <PropertyType>] [= <property_initializer>] [<getter>] [<setter>]
其初始器(initializer)、getter 和 setter 都是可选的。属性类型如果可以从初始器 (或者从其 getter 返回值,如下文所示)中推断出来,也可以省略。
例如:
var allByDefault: Int? // 错误:需要显式初始化器,隐含默认 getter 和 setter var initialized = 1 // 类型 Int、默认 getter 和 setter
一个只读属性的语法和一个可变的属性的语法有两方面的不同:
- 只读属性的用 val开始代替var
- 只读属性不允许 setter
val simple: Int? // 类型 Int、默认 getter、必须在构造函数中初始化 val inferredType = 1 // 类型 Int 、默认 getter
我们可以为属性定义自定义的访问器。如果我们定义了一个自定义的 getter,那么每次访问该属性时都会调用它 (这让我们可以实现计算出的属性)。以下是一个自定义 getter 的示例:
val isEmpty: Boolean get() = this.size == 0
如果我们定义了一个自定义的 setter,那么每次给属性赋值时都会调用它。一个自定义的 setter 如下所示:
var stringRepresentation: String get() = this.toString() set(value) { setDataFromString(value) // 解析字符串并赋值给其他属性 }
按照惯例,setter 参数的名称是 value,但是如果你喜欢你可以选择一个不同的名称。
自 Kotlin 1.1 起,如果可以从 getter 推断出属性类型,则可以省略它:
val isEmpty get() = this.size == 0 // 具有类型 Boolean
如果你需要改变一个访问器的可见性或者对其注解,但是不需要改变默认的实现, 你可以定义访问器而不定义其实现:
var setterVisibility: String = "abc" private set // 此 setter 是私有的并且有默认实现 var setterWithAnnotation: Any? = null @Inject set // 用 Inject 注解此 setter
三、幕后字段和属性
1.隐式幕后字段
Kotlin类不能有字段,但有时在自定义的访问器中需要字段,
为此自动提供隐式幕后字段(backing field),可field标识符访问,
field只能用在属性的访问器中.
var counter = 0 //初始值直接写入到幕后字段 set(value) { if (value >= 0) field = value }
2.显式幕后属性
如果隐式幕后字段不符合需求,可用显式幕后属性(backing property)
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访问私有属性会被优化,不会引入函数调用开销!
四、属性的初始化
1.编译期常量
属性用const修饰符标记,称为编译期常量Compile-Time Constants,需满足以下要求:
位于顶层或者是object的成员
用 String 或原生类型初始化
没有自定义getter
const val DE: String = "This subsystem is deprecated" //编译期常量属性可用在注解中 @Deprecated(DE) fun foo(){ }
2.延迟初始化属性
一般情况,属性声明为非空类型,必须在构造函数中初始化。
然而这不方便,为此可用lateinit修饰符非空属性:
public class MyTest { lateinit var subject: TestSubject @SetUp fun setup() { subject = TestSubject() } @Test fun test() { subject.method() // 直接解引用 } }
lateinit只能用在类体中的var属性,
该属性不能自定义getter和setter方法,
该属性必须是非空类型,不能是原生类型
猜你喜欢
- 2024-09-20 大厂面试原来是这样的,这份面试经你值得拥有
- 2024-09-20 Reactor 3 参考指南:5、Kotlin 支持
- 2024-09-20 Android 开发之 Kotlin 初始篇(kotlin安卓开发教程)
- 2024-09-20 Kotlin必须要掌握的常见高阶函数(kotlin从零到精通)
- 2024-09-20 Kotlin成为Android的官配编程语言
- 2024-09-20 Room & Kotlin 符号的处理(kotlin inline crossinline)
- 2024-09-20 Kotlin - 数据类型(kotlin 函数类型)
- 2024-09-20 Duolingo 如何将 Android App 全部迁至 Kotlin
- 2024-09-20 Kotlin官方文档翻译,类和对象:属性、接口、可见性修饰
- 2024-09-20 怎样把kotlin代码写好(kotlin怎么样)
- 1514℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 563℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 508℃MySQL service启动脚本浅析(r12笔记第59天)
- 486℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 485℃启用MySQL查询缓存(mysql8.0查询缓存)
- 465℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 445℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 442℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)