kotlinkotlin-interop

Data classes in Kotlin


What is the difference between:

Definition 1

data class Person (var name:String, var age:Int)

Definition 2

class Person (var name:String, var age:Int)

Definition 3

class Person (){
    var name:String = ""
    var age:Int = 1
}

In the 3 cases when I use the autocomplete, I saw the same methods available like a POJO... is this the same but in 3 different ways?

enter image description here


Solution

  • Difference in equals, hashCode, & toString

    the most important difference between definition 1 and definitions 2 & 3 is that in definition 1, the equals, hashcode and toString methods are overridden for you:

    Code example:

    NOTE: in Kotlin, the == operator calls an object's .equals() method. see operator overloading on kotlinlang.org for more info.

    data class Person1 (var name:String, var age:Int)
    class Person2 (var name:String, var age:Int)
    
    @Test fun test1()
    {
        val alice1 = Person1("Alice", 22)
        val alice2 = Person1("Alice", 22)
        val bob = Person1("bob", 23)
    
        // alice1 and alice2 are structurally equal, so this returns true.
        println(alice1 == alice2)   // true
    
        // alice1 and bob are NOT structurally equal, so this returns false.
        println(alice1 == bob)      // false
    
        // the toString method for data classes are generated for you.
        println(alice1)     // Person1(name=Alice, age=22)
    }
    
    @Test fun test2()
    {
        val alice1 = Person2("Alice", 22)
        val alice2 = Person2("Alice", 22)
        val bob = Person2("bob", 23)
    
        // even though alice1 and alice2 are structurally equal, this returns false.
        println(alice1 == alice2) // false
        println(alice1 == bob)    // false
    
        // the toString method for normal classes are NOT generated for you.
        println(alice1)  // Person2@1ed6993a
    }
    

    Difference in constructors

    another difference between definitions 1 & 2 and definition 3 is that:

    Code example:

    data class Person1 (var name:String, var age:Int)
    class Person2 (var name:String, var age:Int)
    class Person3 ()
    {
        var name:String = ""
        var age:Int = 1
    }
    
    @Test fun test3()
    {
        Person1("alice",22)     // OK
        Person2("bob",23)       // OK
        Person3("charlie",22)   // error
    
        Person1()   // error
        Person2()   // error
        Person3()   // OK
    }
    

    The copy method

    Finally, another difference between definition 1 and definitions 2 & 3 is that in definition 1, a copy method is generated for it. Here's an example of how it can be used:

    val jack = Person1("Jack", 1)
    val olderJack = jack.copy(age = 2)
    
    // jack.age = 1
    // olderJack.age = 2
    

    Check out the official documentation for data classes on kotlinlang.org!