13

I'm a beginner of Kotlin, I have read some sample code about data class, it seems that the parameter are all val type just like Code A

I need to change some values of data class MSetting, so I design the Code B, could you tell me whether the Code B is good way?

Code A

data class MSetting (
        val _id: Long, 
        val name: String,
        val createdDate: Long,
        val description: String
)

Code B

data class MSetting (
        var _id: Long, 
        var name: String,
        var createdDate: Long,
        var description: String
)
2

3 Answers 3

20

The accepted answer is misleading. Yes, you can use var arguments in data class constructor. But you should avoid it at all costs because it defeats the purpose of data class.

Consider this example:

data class Text(
    val x: String,
    var y: Int,
)

fun main() {
    val t = Text("4124", 1)
    val a = t.hashCode()
    t.y = 125
    val b = t.hashCode()
    println(a)
    println(b)
}

The output will be something like:

49532514
49532638

This means, object t cannot be used in Map/Set, because it's hashCode isn't constant which will lead to ghost-objects in these collections.

The proper way to have modifiable field in data class is:

data class Text(
   val x: String,
) {
   var y: Int
}

This way y isn't included in generated equals, hashCode, toString and problem with Map/Set is avoided.

See kotlin doc for this: https://kotlinlang.org/docs/data-classes.html#properties-declared-in-the-class-body

1
  • 3
    Good point and it's really strange that language creators doesn't care even about warning if that type of usage occurs
    – Andrey-r
    Commented Sep 22, 2022 at 10:28
12

it seems that the parameter are all val type...

NO

could you tell me whether the Code B is good way?

The difference between val and var: Properties declared with val can't be updated over time; its just like constants in java. Properties declared with var can be changed overtime.

It totally depends on your requirement. If you need to change properties over time then go for var; val otherwise. You can mix both in a object without any issue.

Read more about properties in Kotlin documentation here https://kotlinlang.org/docs/reference/properties.html

2
  • 2
    This is not correct @Rohit5k2, Please read this stackoverflow.com/a/73812090/1179638 Commented Dec 26, 2022 at 17:37
  • @AtulBhardwaj it technically is correct, it just doesn't mention that using var as a data class parameter fundamentally changes how this particular data class will behave (which is indeed explained nicely in the answer you've linked). Commented Jan 25 at 14:22
2

I like to use val as a rule of thumb because it makes data class immutable. Of course I am using var but only if it is necessary. Why it is better to make data class immutable? read this.

Not the answer you're looking for? Browse other questions tagged or ask your own question.