Praful Ranjan
Praful Ranjan

Reputation: 117

How to call Kotlin copy() from data class to java class?

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

Answers (3)

Mayur Prajapati
Mayur Prajapati

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

TheOperator
TheOperator

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

phatnhse
phatnhse

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.

Data class defination

Upvotes: 1

Related Questions