Reputation: 117
Suppose I have a data class and want to use copy() and call it in java class.
In kotlin we do like this
data class User(val name: String = "", val age: Int = 0)
fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
val jack = User(name = "Jack", age = 1)
val olderJack = jack.copy(age = 2)`
But in java we can't.
One method is to create copy method in data class and call it in java class using sampleClassObject.copy(...)
.
But the problem is suppose there are total 5 parameters in constructor
and I only want to pass 2 parameters using copy()
in java class how to do that?
Upvotes: 1
Views: 13498
Reputation: 627
This is because Kotlin does supports default parameters Java doesn't. But you can do following.
In Java
User user = new User().copy("Your Name", 10);
System.out.println(user.copy().getName());
In Kotlin
data class User(val name: String = "", val age: Int = 0){
fun copy() = User(name, age)
Keep coding. Keep learning :) }
Upvotes: 2
Reputation: 6496
The reason why copy()
is so useful in Kotlin are named arguments, which allow you to selectively specify only the parameters you need.
In Java, this feature does not exist, so people try to achieve the same using a different paradigm: builders.
By defining a builder in the Kotlin class (unfortunately we cannot use set
properties, because they cannot return this
):
data class User(val name: String, val age: Int) {
class Builder(origin: User) {
private var name: String = origin.name
private var age: Int = origin.age
// also performs operations on 'this' and returns 'this'
fun name(value: String) = this.also { name = value }
fun age(value: Int) = this.also { age = value }
fun build() = User(name, age)
}
}
You could then do something like this:
User user = new User(...);
User copied = new User.Builder(user)
.name("Alfred")
.build();
If you need extra syntactic sugar, you can always add more methods:
// Kotlin
data class User(val name: String, val age: Int) {
...
fun copy() = Builder(this)
}
// Java
User copied = user.copy().name("Alfred").build()
Note that projects such as Lombok can automatically generate a lot of the boilerplate needed.
Upvotes: 9
Reputation: 3940
Not sure how this can be used in the real use case, but this might be helpful.
This is User
class:
data class User(val param1: String = "",
val param2: String = "",
val param3: String = "",
val param4: String = "",
val param5: String = "") {
constructor(param1: String, param2: String) : this(param1, param2,
"This is optional 1",
"This is optional 2",
"This is optional 3")
fun copy(param1: String, param2: String) = User(param1, param2)
}
This is how to make use of it inside java
class:
User user = new User("a", "b").copy("c", "d");
By default, you don't need to do this, data class already has a copy() function
Deriving a data class from a type that already had a copy(...) function with a matching signature is deprecated in Kotlin 1.2 and will be prohibited in Kotlin 1.3.
Upvotes: 1