# Custom getter/setter for properties created by type params

**URL:** <https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46>\
**Category:** Uncategorized\
**Created:** [November 5, 2015, 3:10pm UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46 "2015-11-05T15:10:27Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![leopard2a5](https://avatars.discourse-cdn.com/v4/letter/l/ee7513/32.png) [@leopard2a5](https://discuss.kotlinlang.org/u/leopard2a5)\
**Post date:** [November 5, 2015, 3:10pm UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/1 "2015-11-05T15:10:27Z")

</div>

Hi!

I’m just starting out with kotlin and i was trying to build a simple data class with custom getters/setters. What i want would look like this in Java:

public class JavaPerson {

&nbsp;&nbsp;private final String name;

&nbsp;&nbsp;private int age;

&nbsp;&nbsp;public JavaPerson(final String name, final int age) {

&nbsp;&nbsp;super();

&nbsp;&nbsp;this.name = name;

&nbsp;&nbsp;this.age = age;

&nbsp;&nbsp;}

&nbsp;&nbsp;// default name getter, no setter

&nbsp;&nbsp;// default age getter

&nbsp;&nbsp;public void setAge(final int age) {

&nbsp;&nbsp;System.out.println("Setting age to " + age);

&nbsp;&nbsp;this.age = age;

&nbsp;&nbsp;}

}

However i struggle to get the same thing working in kotlin:

public class Person(val name: String, var age: Int) {

&nbsp;&nbsp;override fun setAge(age: Int) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println("Setting age to " + age);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.age = age

&nbsp;&nbsp;}

&nbsp;&nbsp;// doesn't compile: overrides nothing

&nbsp;&nbsp;public fun setAge(age: Int) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println("Setting age to " + age);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.age = age

&nbsp;&nbsp;}

&nbsp;&nbsp;// fails at compile and/or runtime: java.lang.ClassFormatError: Duplicate method name&signature in class file de/itso/kotlintest/Person

}

I’ve also tried to do it like this:

public class Person private constructor (val name: String) {

&nbsp;&nbsp;private var age: Int

&nbsp;&nbsp;public constructor(name: String, age: Int) : this(name) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.age = age

&nbsp;&nbsp;}

}

But this fails, as i have to initialize age when i declare it, although i assign it in the only public constructor. I would consider this a workaround, even if it compiled.

Can anybody help me here?

---

<div class="post-metadata">

**Author:** ![yole](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/yole/32/1425_2.png) [@yole](https://discuss.kotlinlang.org/u/yole)\
**Post date:** [November 5, 2015, 4:20pm UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/2 "2015-11-05T16:20:20Z")

</div>

If you need a custom getter or setter for your property, you cannot declare it in the primary constructor parameter. You need to declare a property in the body of the class.

class Person(val name: String, age: Int) {  
&nbsp;&nbsp;var age: Int = age  
&nbsp;&nbsp;set(value) {  
&nbsp;&nbsp;println(“Setting age to $value”)  
&nbsp;&nbsp;field = value;  
&nbsp;&nbsp;}  
}

---

<div class="post-metadata">

**Author:** ![leopard2a5](https://avatars.discourse-cdn.com/v4/letter/l/ee7513/32.png) [@leopard2a5](https://discuss.kotlinlang.org/u/leopard2a5)\
**Post date:** [November 6, 2015, 7:27am UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/3 "2015-11-06T07:27:30Z")

</div>

I see! I was under the impression that this was a redeclaration, as the property exists as a type param as well as as a property. Unfortunately the current eclipse plugin seems to treat this as an error, as it can't resolve 'field'.

---

<div class="post-metadata">

**Author:** ![mikrobi](https://avatars.discourse-cdn.com/v4/letter/m/f04885/32.png) [@mikrobi](https://discuss.kotlinlang.org/u/mikrobi)\
**Post date:** [April 20, 2016, 2:22pm UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/4 "2016-04-20T14:22:34Z")

</div>

How can we deal with this when working with data classes?

For data classes all primary constructor parameters need to be marked as `val` or `var`. So when I want to have a special setter for one of my (required/non-optional) data class properties, I have to implement `equals()`, `hashCode()` `toString()` etc. on my own or is there another cool way?

---

<div class="post-metadata">

**Author:** ![elect](https://avatars.discourse-cdn.com/v4/letter/e/e480ec/32.png) [@elect](https://discuss.kotlinlang.org/u/elect)\
**Post date:** [October 8, 2016, 10:50am UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/5 "2016-10-08T10:50:43Z")

</div>

Any news on the @mikrobi question?

---

<div class="post-metadata">

**Author:** ![yole](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/yole/32/1425_2.png) [@yole](https://discuss.kotlinlang.org/u/yole)\
**Post date:** [October 10, 2016, 8:45am UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/6 "2016-10-10T08:45:27Z")

</div>

You can use a backing property in this situation:

```auto
data class C(private val _propertyWithSetter: String) {
    val propertyWithSetter: String
        get() = _propertyWithSetter
        set(value) {
            /* execute setter logic */
            _propertyWithSetter = value
        }
}

```

---

<div class="post-metadata">

**Author:** ![elect](https://avatars.discourse-cdn.com/v4/letter/e/e480ec/32.png) [@elect](https://discuss.kotlinlang.org/u/elect)\
**Post date:** [October 10, 2016, 1:39pm UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/7 "2016-10-10T13:39:59Z")

</div>

Thanks, I think that should go in the wiki 🙂

---

<div class="post-metadata">

**Author:** ![serajin00](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@serajin00](https://discuss.kotlinlang.org/u/serajin00)\
**Post date:** [November 11, 2016, 5:53am UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/8 "2016-11-11T05:53:04Z")

</div>

But the name of constructor argument starts with “\_” is quite a problem. (eg. named argument call, copy, …)  
And if we have many properties many boilerplate will made.

I think there should be a better way for ‘private set applied to constructor var’.

---

<div class="post-metadata">

**Author:** ![pdvrieze](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/pdvrieze/32/1882_2.png) [@pdvrieze](https://discuss.kotlinlang.org/u/pdvrieze)\
**Post date:** [November 11, 2016, 8:41am UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/9 "2016-11-11T08:41:10Z")

</div>

The compiler is actually smart enough to do the right thing for the following code:

```
class person(name:string) {
    var name:String = name
      private set

  // Rest of the class
}

```

---

<div class="post-metadata">

**Author:** ![serajin00](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@serajin00](https://discuss.kotlinlang.org/u/serajin00)\
**Post date:** [November 11, 2016, 10:13am UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/10 "2016-11-11T10:13:49Z")

</div>

I Agree. Clean constructor and property expression.

But not for data classes.

---

<div class="post-metadata">

**Author:** ![fab1an](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fab1an/32/1934_2.png) [@fab1an](https://discuss.kotlinlang.org/u/fab1an)\
**Post date:** [November 17, 2016, 10:13am UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/11 "2016-11-17T10:13:01Z")

</div>

I ran into the exact same problem.

---

<div class="post-metadata">

**Author:** ![rwoln](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/rwoln/32/2704_2.png) [@rwoln](https://discuss.kotlinlang.org/u/rwoln)\
**Post date:** [June 5, 2017, 4:17pm UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/12 "2017-06-05T16:17:28Z")

</div>

I’m facing something very similar, in which I need to modify a parameter on its initial construction, and would prefer to use a data class. In particular, I am writing a **Direction** class for a three-dimensional unit vector using the Apache Commons Math library Vector3D; the norm of the vector should always be one. What I wish I could write is something like:

```
data class Direction(val vector: Vector3D set(value) { field = vector.normalize() } ) { ... }

```

As it is I am not using a data class, and thus am re-implementing my own equals(), hash(), …

---

<div class="post-metadata">

**Author:** ![hladik.rudolf](https://avatars.discourse-cdn.com/v4/letter/h/7ea924/32.png) [@hladik.rudolf](https://discuss.kotlinlang.org/u/hladik.rudolf)\
**Post date:** [August 1, 2017, 2:51pm UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/13 "2017-08-01T14:51:04Z")

</div>

I have similar problem. Firebase cant parse my data class completly. It can parse all params except for one var is\_captain:String? = null

I tried to write custom get and set as mentioned above  
data class Member(var \_is\_captain: String? = null) {  
{  
var is\_captain: String?  
get() = \_is\_captain  
set(value) {  
\_is\_captain = value  
}  
}

but it still throws ClassMapper: No setter/field for is\_captain found

---

<div class="post-metadata">

**Author:** ![dbdeveloper](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dbdeveloper/32/3838_2.png) [@dbdeveloper](https://discuss.kotlinlang.org/u/dbdeveloper)\
**Post date:** [September 4, 2017, 5:16pm UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/14 "2017-09-04T17:16:50Z")

</div>

Hi! I found one behavior I don’t understand:

```
class User( nameParam: String ) {
    var name : String = nameParam // why is nameParam saved directly into name.field here ?!?
        set(value) {
            println("Set is invoked")
            field = value.toUpperCase() + "!!!"
        }
}

fun main(args: Array<String>) {
    val ivan = User("Ivan") // <<- setter is not invoked here!
    println(ivan.name)

    ivan.name = "Ivan" // <<- but now it is invoked 
    println(ivan.name)
}

```

* * *

Result of execution I expect:

> ```
> Set is invoked
> IVAN!!!
> Set is invoked
> IVAN!!!
> 
> ```

BUT I SEE THIS:

> ```
> Ivan
> Set is invoked
> IVAN!!! 
> 
> ```

(tested on [https://try.kotlinlang.org](https://try.kotlinlang.org) on all available Kotlin’s versions)

---

<div class="post-metadata">

**Author:** ![yole](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/yole/32/1425_2.png) [@yole](https://discuss.kotlinlang.org/u/yole)\
**Post date:** [September 4, 2017, 8:42pm UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/15 "2017-09-04T20:42:42Z")

</div>

Yes, that’s correct. The initializer of a property is stored directly into a backing field, without invoking the setter.

---

<div class="post-metadata">

**Author:** ![dbdeveloper](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dbdeveloper/32/3838_2.png) [@dbdeveloper](https://discuss.kotlinlang.org/u/dbdeveloper)\
**Post date:** [September 5, 2017, 4:20am UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/16 "2017-09-05T04:20:44Z")

</div>

Thank you for explanation. This behavior is not very clear though. I guess you use it to initialize internal field, right?  
So, to achieve my aim I want to use init {} block:

```
class User(nameParam: String) {
  var name : String = <init_value>
     set(value) { ... }
  init {
    name = nameParam
  }
}

```

---

<div class="post-metadata">

**Author:** ![alanfo](https://avatars.discourse-cdn.com/v4/letter/a/bbe5ce/32.png) [@alanfo](https://discuss.kotlinlang.org/u/alanfo)\
**Post date:** [September 5, 2017, 1:52pm UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/17 "2017-09-05T13:52:45Z")

</div>

It does in fact say in the [documentation](https://kotlinlang.org/docs/reference/properties.html#backing-fields) that the initializer value is written directly to the backing field.

Consequently, if you do want the setter to be called, you have to do this in an `init` block as you’re now doing.

However, an unsatisfactory aspect of doing this is that you still need to provide an initial value for the backing field which is therefore, in effect, being initialized twice. You can’t, of course, use `lateinit` if there’s a custom setter.

Whilst the choice of initial value isn’t really a problem for primitives or String (you can always use `""` for the latter), it could be a problem for other types and you may therefore have to resort to making the property nullable.

I’m not aware of any way to avoid this double initialization.

---

<div class="post-metadata">

**Author:** ![tieskedh](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/tieskedh/32/2816_2.png) [@tieskedh](https://discuss.kotlinlang.org/u/tieskedh)\
**Post date:** [September 7, 2017, 9:55pm UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/18 "2017-09-07T21:55:48Z")

</div>

What about the lazy delegate?

---

<div class="post-metadata">

**Author:** ![ilogico](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ilogico/32/3725_2.png) [@ilogico](https://discuss.kotlinlang.org/u/ilogico)\
**Post date:** [September 8, 2017, 12:26am UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/19 "2017-09-08T00:26:34Z")

</div>

Can’t you have a proxy function like this:

```
class User( nameParam: String ) {
    var name : String = transformValue(nameParam)
        set(value) {
            field = transformValue(value)
        }

}

private fun transformValue(value: String): String {
    println("Set is invoked")
    return value.toUpperCase() + "!!!"
}

```

It might not be as elegant, but I don’t see why it wouldn’t work. It can of course be a method as well.

---

<div class="post-metadata">

**Author:** ![alanfo](https://avatars.discourse-cdn.com/v4/letter/a/bbe5ce/32.png) [@alanfo](https://discuss.kotlinlang.org/u/alanfo)\
**Post date:** [September 8, 2017, 4:10pm UTC](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46/20 "2017-09-08T16:10:06Z")

</div>

@tieskedh

Although there are some similarities, the `lazy` delegate is really trying to solve a different problem to what we have here.

@ilogico

Whilst your approach should work, I think it might be a case of the cure being worse than the disease!

It dawned on me after making my previous post that, if you’re going to call the setter in `init`, then you might as well always initialize the property to exactly the same value. So there isn’t really a problem choosing a suitable initial value even for non-primitive types.

The double initialization problem remains (as, frankly, it does in many other OO languages) though at the end of the day it’s not going to cost us many clock cycles 🙂

[Next page](https://discuss.kotlinlang.org/t/custom-getter-setter-for-properties-created-by-type-params/46.md?page=2)
