[英]Kotlin data class copy function not working when called from java class
Maybe I'm misinterpreting how the copy
function of a data
class works or maybe there's a bug, but the following is an example of the copy
function not working as expected:也许我误解了data
类的copy
功能是如何工作的,或者可能存在错误,但以下是copy
功能未按预期工作的示例:
Kotlin:科特林:
data class A {
public var x: String? = null
public var y: String? = null
public var z: B = B.ONE
}
enum class B {
ONE
TWO
THREE
}
Java爪哇
A a1 = new A()
a1.setX("Hello")
a1.setY("World")
a1.setZ(B.TWO)
A a2 = a1.copy()
// a2.x is null
// a2.y is null
// a2.z is B.ONE
It seems that copy
is just making a new instance of A
and not copying the values.似乎copy
只是制作A
的新实例而不是复制值。 If I put the variables in the constructor, the values are assigned, but then it's no different than constructing a new instance.如果我将变量放在构造函数中,则会分配值,但这与构造新实例没有什么不同。
Okay, I missed this sentence in the docs:好的,我在文档中遗漏了这句话:
If any of these functions is explicitly defined in the class body or inherited from the base types, it will not be generated.如果这些函数中的任何一个在类主体中显式定义或从基类型继承,则不会生成它。
Which, infact, makes copy
no better than a constructor for Java interop.事实上,这使得copy
并不比 Java 互操作的构造函数更好。
What you can do to get around the limitations of Kotlin's copy(), is to create your own copy function inside your data class.为了绕过 Kotlin 的 copy() 的限制,您可以做的是在您的数据类中创建您自己的复制函数。 Example below:下面的例子:
data class User(val name : String, val property: String) {
fun copy() : User {
//uses the fields name and property defined in the constructor
return User(name,property)
}
//or if you need a copy with a changed field
fun copy(changedProperty : String) : User {
return User(name, changedProperty)
}
}
For interop with java you can make function that use kotlin generated .copy对于与 java 的互操作,您可以创建使用 kotlin 生成的 .copy 的函数
@Entity
data class User(@PrimaryKey var id: Int = 0,
var firstName: String? = null,
var lastName: String? = null,
var phone: String? = null,
var email: String? = null,
var phoneCode: String? = null,
var tokenId: String? = null,
var provider: SocialProvider? = null) : Serializable {
var countryCodeIso: String? = null
set(countryCodeIso) {
if (countryCodeIso != null) {
field = countryCodeIso.toLowerCase()
}
}
fun javaCopy(): User {
val user = copy()
user.countryCodeIso = countryCodeIso
return user
}}
This question is high in search rankings, and potentially confusing for those new to kotlin, since the question's sample code is not typical kotlin code or usage of the copy function.这个问题在搜索排名中很高,对于那些刚接触 kotlin 的人来说可能会造成混淆,因为问题的示例代码不是典型的 kotlin 代码或复制函数的用法。 I added some sample code below to help clarify what's going on, and also show typical usage of a data class.我在下面添加了一些示例代码来帮助阐明发生了什么,并展示了数据类的典型用法。
In short, the copy
function is most useful when called from a kotlin class.简而言之, copy
函数在从 kotlin 类调用时最有用。 I agree that its behavior isn't obvious when called from java code.我同意从 java 代码调用时它的行为并不明显。
//
// A.kt
//
// this is an idiomatic kotlin data class. note the parens around the properties, not braces.
data class A(
val x: String? = null,
val y: String? = null,
val z: B = B.ONE
) {
// this javaCopy function is completely unnecessary when being called from kotlin; it's only here to show a fairly simple way to make kotlin-java interop a little easier (like what Nokuap showed).
fun javaCopy(): A {
return this.copy()
}
}
enum class B {
ONE,
TWO,
THREE
}
fun main() {
val a1 = A("Hello", "World", B.TWO)
// here's what copy usage looks like for idiomatic kotlin code.
val a2 = a1.copy()
assert(a2.x == "Hello")
assert(a2.y == "World")
assert(a2.z == B.TWO)
// more typical is to `copy` the object and modify one or more properties during the copy. e.g.:
val a3 = a1.copy(y = "Friend")
assert(a2.x == "Hello")
assert(a3.y == "Friend")
}
public class App {
public static void main(String[] args) {
A a1 = new A("Hello", "World", B.TWO);
// the kotlin copy function is primarily meant for kotlin <-> kotlin interop
// copy works when called from java, but it requires all the args.
// calling the `javaCopy` function gives the expected behavior.
A a2 = a1.javaCopy();
assert a2.getX().equals("Hello");
assert a2.getY().equals("World");
assert a2.getZ().equals(B.TWO);
}
}
Official docs on data classes, including the copy
function:关于数据类的官方文档,包括copy
功能:
https://kotlinlang.org/docs/reference/data-classes.html https://kotlinlang.org/docs/reference/data-classes.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.