Properties in Kotlin classes can be declared either as mutable using the var keyword, or as read-only using the val keyword.
```
class Address {
var name: String = "Holmes, Sherlock"
var street: String = "Baker"
var city: String = "London"
var state: String? = null
var zip: String = "123456"
}
```
To use a property, simply refer to it by name:
```
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
}
```
The full syntax for declaring a property is
```
var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]
```
The initializer, getter and setter are optional. Property type is optional if it can be inferred from the initializer (or from the getter return type, as shown below).
```
var allByDefault: Int? // error: explicit initializer required, default getter and setter implied
var initialized = 1 // has type Int, default getter and setter
```
The full syntax of a read-only property declaration differs from a mutable one in two ways: it starts with val instead of var and does not allow a setter:
```
val simple: Int? // has type Int, default getter, must be initialized in constructor
val inferredType = 1 // has type Int and a default getter
```
We can define custom accessors for a property. If we define a custom getter, it will be called every time we access the property (this allows us to implement a computed property). Here's an example of a custom getter:
```
val isEmpty: Boolean
get() = this.size == 0
```
If we define a custom setter, it will be called every time we assign a value to the property. A custom setter looks like this:
```
var stringRepresentation: String
get() = this.toString()
set(value) {
setDataFromString(value) // parses the string and assigns values to other properties
}
```
By convention, the name of the setter parameter is value, but you can choose a different name if you prefer.
Since Kotlin 1.1, you can omit the property type if it can be inferred from the getter:
```
val isEmpty get() = this.size == 0 // has type Boolean
```
If you need to change the visibility of an accessor or to annotate it, but don't need to change the default implementation, you can define the accessor without defining its body:
```
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 is generated only if a property uses the default implementation of getter/setter. If you see the following code with perspective of Java. It looks correct. However in Kotlin it’ll throw StackOverFlow.
```
class User{
var firstName : String //backing field generated
get() = firstName
set(value) {firstName = value}
var lastName : String //backing field generated
get() = lastName
set(value) {lastName = value}
val name : String //no backing field generated
get() = "{$firstName $lastName}"
var address : String = "XYZ" //^because there is no default
//^implementation of an accessor
}
```
In Kotlin the above code snippet will throw StackOverflow because when we access or set property firstName or lastName the default accessor will be called. So in Kotlin user.firstName = "value” is same as Java’s user.setFirstName("value").
So when set(value) {firstName = "value"} is called, then a recursive call happens and compiler throws a StackOverflow exception because we are calling setter inside the setter.
Solution to this problem is to user backing fields. In Kotlin a backing field can be accessed using field keyword inside accessors.
In Kotlin, a field is only used when needed as part of a property to hold its value in memory. Fields can not be declared directly. However, when a property needs a backing field, Kotlin provides it automatically. This backing field can be referenced in the accessors using the field identifier:
```
var counter = 0 // Note: the initializer assigns the backing field directly
set(value) {
if (value >= 0) field = value
}
```
The field identifier can only be used in the accessors of the property.
A backing field will be generated for a property if it uses the default implementation of at least one of the accessors, or if a custom accessor references it through the field identifier.
For example, in the following case there will be no backing field:
```
val isEmpty: Boolean
get() = this.size == 0
```
If you want to do something that does not fit into this "implicit backing field" scheme, you can always fall back to having a backing property:
```
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")
}
```