有什么区别:
定义1
data class Person (var name:String, var age:Int)
定义2
class Person (var name:String, var age:Int)
定义3
class Person (){
var name:String = ""
var age:Int = 1
}
在我使用自动完成的3种情况中,我看到像POJO一样的可用方法......是相同但有3种不同的方式吗?
答案 0 :(得分:11)
equals
,hashCode
和& toString
定义1 与定义2& 2之间最重要的区别3 是定义1 中的内容,equals
,hashcode
和toString
方法会被覆盖:
equals
和hashCode
方法测试结构平等 toString
方法返回一个漂亮的,人性化的字符串代码示例:
注意:在Kotlin中,==
运算符调用对象的.equals()
方法。见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
}
定义1和&之间的另一个区别2 和定义3 是:
代码示例:
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
}
copy
方法最后,定义1 和定义2& 2之间的另一个区别3 是定义1 ,为其生成copy
method。以下是如何使用它的示例:
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!
答案 1 :(得分:1)
简而言之:
name
和age
name
和age
""
和{{1}分配默认值1
和name
}分别详细回答
这里要理解的是data class的概念。
创建主要目的是保存数据的类非常普遍。如果希望您的类方便保存数据,则需要覆盖通用对象方法:
toString()
-字符串表示形式equals()
-对象相等hashCode()
-哈希容器注意:age
用于structural equality,通常用equals()
实现。
通常,这些方法的实现非常简单,IDE可以帮助您自动生成它们。
但是,在Kotlin中,您不必概括所有这些样板代码。如果将修饰符hashCode()
添加到类中,则会自动为您添加必要的方法。 data
和equals()
方法考虑了在主构造函数中声明的所有属性。 hashCode()
的格式为toString()
。
此外,当您将某个类标记为数据类时,也会自动生成方法ClassName(parm1=value1, param2=value2, ...)
,该方法使您可以复制现有实例。当您将实例用作copy()
的键或处理多线程代码时,此功能非常方便。
回到您的问题:
HashMap
方法copy()
方法(如果需要)copy()
方法,并且自从实现copy()
方法以来没有意义。您的主要构造函数没有参数即使不要求数据类的属性为copy()
,即,您也可以像在代码中那样使用val
,但强烈建议您使用只读属性,以使实例不可变。
最后,当您将一个类标记为数据类时,编译器还会生成按声明顺序与属性对应的var
函数。
答案 2 :(得分:0)
定义1(data class Person(var name: String, var age: Int
)相当于
/* 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)
定义2(class Person(var name: String, var age: Int
[no data
修饰符])相当于
class Person(var name: String, var age: Int) {
}
val person = Person("Name", 123)
定义3相当于
class Person() {
var name: String = ""
var age: Int = 1
}
val person = Person() // name = "", age = 1 (by default)
person.name = "Name"
person.age = 123
答案 3 :(得分:0)
只是添加一个 Eric 接受的答案没有提到的不同之处。
数据类可以参与解构声明。
如果我们有
class Person(val name: String, val age: Int)
data class Person2(val name: String, val age: Int)
然后
fun main() {
val person = Person("Kal", 34); //normal class instance
val person2 = Person2("Kal", 34); //data class instance
val (name, age) = person; //This does not compile and shows error
//Destructuring declaration initializer of type Employee must have a 'component1()' function
//Destructuring declaration initializer of type Employee must have a 'component2()' function
val (name2, age2) = person2; //no problem here
}