Kotlin 中的 getter 和 setter
Getters and Setters in Kotlin
例如,在 Java 中,我可以自己编写 getter(由 IDE 生成)或在 lombok 中使用 @Getter 之类的注解 - 这非常简单。
然而 Kotlin 有 getters and setters by default。
但是我不明白怎么用。
我想成功,可以说 - 类似于 Java:
private val isEmpty: String
get() = this.toString() //making this thing public rises an error: Getter visibility must be the same as property visibility.
那么 getter 是如何工作的呢?
Getter 和 setters 是在 Kotlin 中自动生成的。如果你写:
val isEmpty: Boolean
等于下面的Java代码:
private final Boolean isEmpty;
public Boolean isEmpty() {
return isEmpty;
}
在您的情况下,私有访问修饰符是多余的 - isEmpty 默认是私有的,只能由 getter 访问。当您尝试获取对象的 isEmpty 属性 时,您实际上调用了 get 方法。为了更好地理解 Kotlin 中的 getters/setters:下面的两个代码示例是相等的:
var someProperty: String = "defaultValue"
和
var someProperty: String = "defaultValue"
get() = field
set(value) { field = value }
我还想指出 getter 中的 this
不是您的 属性 - 它是 class 实例。如果你想在 getter 或 setter 中访问字段的值,你可以使用保留字 field
:
val isEmpty: Boolean
get() = field
如果您只想在 public 访问中有一个 get 方法 - 您可以编写此代码:
var isEmpty: Boolean
private set
由于 set 访问器附近的 private 修饰符,您只能在对象内部的方法中设置此值。
关于 属性 访问器 visibility modifiers 的规则如下:
Getter var
和 val
属性 的可见性应该与 相同 属性 的可见性,因此您只能显式复制 属性 修饰符,但它是多余的:
protected val x: Int
protected get() = 0 // No need in `protected` here.
Setter var
属性 的可见性应 与 属性 相同或更宽松 ] 可见度:
protected var x: Int
get() = 0
private set(x: Int) { } // Only `private` and `protected` are allowed.
在 Kotlin 中,属性总是通过 getter 和 setter 访问,因此没有必要使用 public
访问器制作 属性 private
在 Java -- its backing field (if present) 中已经是私有的。因此,属性 访问器上的可见性修饰符仅用于降低 setter 可见性:
对于具有支持字段和默认访问器的 属性:
var x = 0 // `public` by default
private set
对于没有支持字段的 属性:
var x: Int // `public` by default
get() = 0
protected set(value: Int) { }
Getter 在 kotlin 中默认为 public,但您可以将 setter 设置为私有并使用 class 中的一种方法设置值。像这样。
/**
* Created by leo on 17/06/17.*/
package foo
class Person() {
var name: String = "defaultValue"
private set
fun foo(bar: String) {
name = bar // name can be set here
}
}
fun main(args: Array<String>) {
var p = Person()
println("Name of the person is ${p.name}")
p.foo("Jhon Doe")
println("Name of the person is ${p.name}")
}
您可以查看此教程了解更多信息:
Yet Another Kotlin Tutorial for Android Developers
Properties
In Kotlin world, classes cannot have fields, just properties. var
keyword tells us the property is mutable, in contrast to val. Let’s
see an example:
class Contact(var number: String) {
var firstName: String? = null
var lastName: String? = null
private val hasPrefix : Boolean
get() = number.startsWith("+")
}
There is not much code, but lots of things are happening behind the
scenes. We will go through it step by step. First of all, we created a
public final class Contact.
This is the primary rule we have to face: if not specified otherwise,
classes are public and final by default (by the way, the same is for
class methods). If you want to inherit from class, mark it with open
keyword.
1) Kotlin
中 属性 firstName
的示例默认值 setter
和 getter
class Person {
var firstName: String = ""
get() = field // field here ~ `this.firstName` in Java or normally `_firstName` is C#
set(value) {
field = value
}
}
正在使用
val p = Person()
p.firstName = "A" // access setter
println(p.firstName) // access getter (output:A)
如果你的setter
或getter
与上面完全相同,你可以删除它,因为它是不需要
2) 示例自定义 setter 和 getter。
const val PREFIX = "[ABC]"
class Person {
// set: if value set to first name have length < 1 => throw error else add prefix "ABC" to the name
// get: if name is not empty -> trim for remove whitespace and add '.' else return default name
var lastName: String = ""
get() {
if (!field.isEmpty()) {
return field.trim() + "."
}
return field
}
set(value) {
if (value.length > 1) {
field = PREFIX + value
} else {
throw IllegalArgumentException("Last name too short")
}
}
}
正在使用
val p = Person()
p.lastName = "DE " // input with many white space
println(p.lastName) // output:[ABC]DE.
p.lastName = "D" // IllegalArgumentException since name length < 1
更多
我从 Java 开始学习 Kotlin,所以我对 field
和 property
感到困惑,因为在 Java 中没有 property
.
经过一些搜索,我看到 Kotlin 中的 field
和 property
看起来像 C# (What is the difference between a field and a property?)
这里有一些相关的 post,其中讨论了 Java 和 Kotlin 中的 field
和 property
。
does java have something similar to C# properties?
https://blog.kotlin-academy.com/kotlin-programmer-dictionary-field-vs-property-30ab7ef70531
如果我错了请纠正我。希望对你有帮助
这是 Kotlin getter 和 setter 的一个实用的真实示例(查看更多详细信息 here):
// Custom Getter
val friendlyDescription get(): String {
val isNeighborhood = district != null
var description = if (isNeighborhood) "Neighborhood" else "City"
description += " in"
if (isNeighborhood) {
description += " $city,"
}
province?.let {
if (it.isNotEmpty()) {
description += " $it,"
}
}
description += " $country"
return description
}
print(myLocation.friendlyDescription) // "Neighborhood in Denver, Colorado, United States"
// Custom Setter
enum class SearchResultType {
HISTORY, SAVED, BASIC
}
private lateinit var resultTypeString: String
var resultType: SearchResultType
get() {
return enumValueOf(resultTypeString)
}
set(value) {
resultTypeString = value.toString()
}
result.resultType = SearchResultType.HISTORY
print(result.resultTypeString) // "HISTORY"
如果您有一个 Var,那么您可以:
var property: String = "defVal"
get() = field
set(value) { field = value }
但是对于 Val,一旦赋值就不能设置,所以不会有 setter 块:
val property: String = "defVal"
get() = field
或者如果您不想 setter 那么:
val property: String = "defVal"
private set
例如,在 Java 中,我可以自己编写 getter(由 IDE 生成)或在 lombok 中使用 @Getter 之类的注解 - 这非常简单。
然而 Kotlin 有 getters and setters by default。 但是我不明白怎么用。
我想成功,可以说 - 类似于 Java:
private val isEmpty: String
get() = this.toString() //making this thing public rises an error: Getter visibility must be the same as property visibility.
那么 getter 是如何工作的呢?
Getter 和 setters 是在 Kotlin 中自动生成的。如果你写:
val isEmpty: Boolean
等于下面的Java代码:
private final Boolean isEmpty;
public Boolean isEmpty() {
return isEmpty;
}
在您的情况下,私有访问修饰符是多余的 - isEmpty 默认是私有的,只能由 getter 访问。当您尝试获取对象的 isEmpty 属性 时,您实际上调用了 get 方法。为了更好地理解 Kotlin 中的 getters/setters:下面的两个代码示例是相等的:
var someProperty: String = "defaultValue"
和
var someProperty: String = "defaultValue"
get() = field
set(value) { field = value }
我还想指出 getter 中的 this
不是您的 属性 - 它是 class 实例。如果你想在 getter 或 setter 中访问字段的值,你可以使用保留字 field
:
val isEmpty: Boolean
get() = field
如果您只想在 public 访问中有一个 get 方法 - 您可以编写此代码:
var isEmpty: Boolean
private set
由于 set 访问器附近的 private 修饰符,您只能在对象内部的方法中设置此值。
关于 属性 访问器 visibility modifiers 的规则如下:
Getter
var
和val
属性 的可见性应该与 相同 属性 的可见性,因此您只能显式复制 属性 修饰符,但它是多余的:protected val x: Int protected get() = 0 // No need in `protected` here.
Setter
var
属性 的可见性应 与 属性 相同或更宽松 ] 可见度:protected var x: Int get() = 0 private set(x: Int) { } // Only `private` and `protected` are allowed.
在 Kotlin 中,属性总是通过 getter 和 setter 访问,因此没有必要使用 public
访问器制作 属性 private
在 Java -- its backing field (if present) 中已经是私有的。因此,属性 访问器上的可见性修饰符仅用于降低 setter 可见性:
对于具有支持字段和默认访问器的 属性:
var x = 0 // `public` by default private set
对于没有支持字段的 属性:
var x: Int // `public` by default get() = 0 protected set(value: Int) { }
Getter 在 kotlin 中默认为 public,但您可以将 setter 设置为私有并使用 class 中的一种方法设置值。像这样。
/**
* Created by leo on 17/06/17.*/
package foo
class Person() {
var name: String = "defaultValue"
private set
fun foo(bar: String) {
name = bar // name can be set here
}
}
fun main(args: Array<String>) {
var p = Person()
println("Name of the person is ${p.name}")
p.foo("Jhon Doe")
println("Name of the person is ${p.name}")
}
您可以查看此教程了解更多信息:
Yet Another Kotlin Tutorial for Android Developers
Properties
In Kotlin world, classes cannot have fields, just properties. var keyword tells us the property is mutable, in contrast to val. Let’s see an example:
class Contact(var number: String) { var firstName: String? = null var lastName: String? = null private val hasPrefix : Boolean get() = number.startsWith("+") }
There is not much code, but lots of things are happening behind the scenes. We will go through it step by step. First of all, we created a public final class Contact.
This is the primary rule we have to face: if not specified otherwise, classes are public and final by default (by the way, the same is for class methods). If you want to inherit from class, mark it with open keyword.
1) Kotlin
中 属性firstName
的示例默认值 setter
和 getter
class Person {
var firstName: String = ""
get() = field // field here ~ `this.firstName` in Java or normally `_firstName` is C#
set(value) {
field = value
}
}
正在使用
val p = Person()
p.firstName = "A" // access setter
println(p.firstName) // access getter (output:A)
如果你的setter
或getter
与上面完全相同,你可以删除它,因为它是不需要
2) 示例自定义 setter 和 getter。
const val PREFIX = "[ABC]"
class Person {
// set: if value set to first name have length < 1 => throw error else add prefix "ABC" to the name
// get: if name is not empty -> trim for remove whitespace and add '.' else return default name
var lastName: String = ""
get() {
if (!field.isEmpty()) {
return field.trim() + "."
}
return field
}
set(value) {
if (value.length > 1) {
field = PREFIX + value
} else {
throw IllegalArgumentException("Last name too short")
}
}
}
正在使用
val p = Person()
p.lastName = "DE " // input with many white space
println(p.lastName) // output:[ABC]DE.
p.lastName = "D" // IllegalArgumentException since name length < 1
更多
我从 Java 开始学习 Kotlin,所以我对 field
和 property
感到困惑,因为在 Java 中没有 property
.
经过一些搜索,我看到 Kotlin 中的 field
和 property
看起来像 C# (What is the difference between a field and a property?)
这里有一些相关的 post,其中讨论了 Java 和 Kotlin 中的 field
和 property
。
does java have something similar to C# properties?
https://blog.kotlin-academy.com/kotlin-programmer-dictionary-field-vs-property-30ab7ef70531
如果我错了请纠正我。希望对你有帮助
这是 Kotlin getter 和 setter 的一个实用的真实示例(查看更多详细信息 here):
// Custom Getter
val friendlyDescription get(): String {
val isNeighborhood = district != null
var description = if (isNeighborhood) "Neighborhood" else "City"
description += " in"
if (isNeighborhood) {
description += " $city,"
}
province?.let {
if (it.isNotEmpty()) {
description += " $it,"
}
}
description += " $country"
return description
}
print(myLocation.friendlyDescription) // "Neighborhood in Denver, Colorado, United States"
// Custom Setter
enum class SearchResultType {
HISTORY, SAVED, BASIC
}
private lateinit var resultTypeString: String
var resultType: SearchResultType
get() {
return enumValueOf(resultTypeString)
}
set(value) {
resultTypeString = value.toString()
}
result.resultType = SearchResultType.HISTORY
print(result.resultTypeString) // "HISTORY"
如果您有一个 Var,那么您可以:
var property: String = "defVal"
get() = field
set(value) { field = value }
但是对于 Val,一旦赋值就不能设置,所以不会有 setter 块:
val property: String = "defVal"
get() = field
或者如果您不想 setter 那么:
val property: String = "defVal"
private set