问题
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 availables like a POJO... is the same but 3 differents ways?
回答1:
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:
equals
andhashCode
methods test for structural equalitytoString
method returns a nice, human-friendly string
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:
- definitions 1 & 2 both have a constructor that takes 2 parameters
- definition 3 only has a no argument constructor that assigns default values to the class members.
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!
回答2:
Definition 1 (data class Person(var name: String, var age: Int
) is the equivalent of
/* every class by default in kotlin is final but a data class CAN'T be open */
final class Person(var name: String, var age: Int) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other?.javaClass != javaClass) return false
other as Person
if (name != other.name) return false
if (age != other.age) return false
return true
}
override fun hashCode(): Int {
var result = name.hashCode()
result = 31 * result + age
return result
}
}
val person = Person("Name", 123)
Definition 2 (class Person(var name: String, var age: Int
[no data
modifier]) is the equivalent of
class Person(var name: String, var age: Int) {
}
val person = Person("Name", 123)
Definition 3 is the equivalent of
class Person() {
var name: String = ""
var age: Int = 1
}
val person = Person() // name = "", age = 1 (by default)
person.name = "Name"
person.age = 123
来源:https://stackoverflow.com/questions/45069337/data-classes-in-kotlin