Hi, I’d like to use data class with private constr...
# server
u
Hi, I’d like to use data class with private constructor, and now searching the way to make
copy
method not visible from outside. Many people provide workarounds and I found this. Seems interesting but I don’t know how it works. This uses sealed class and seems
hashCode
equals
toString
method of data class can be still used from outside, while
copy
method is not. Why only
copy
method is hidden by this way?
Copy code
// Original data class with private constructor
data class User private constructor(val name: String, val id: Int){
    companion object{
        fun of(name:String, id: Int): User{
            return User(if(name.isEmpty()) "Unknown" else name, id)
        }
    }
}
Copy code
// Workaround with sealed class
sealed class User {
    companion object {
        fun of(name: String, id: Int): User = UserData(if (name.isEmpty()) "Unknown" else name, id)
    }

    abstract val name: String
    abstract val id: Int

    private data class UserData(override val name: String, override val id: Int) : User()
}
e
because the data class is private, its methods (such as copy) are not accessible
u
because the data class is private, its methods (such as copy) are not accessible
So
equals
and
hashCode
in this case don’t belong to data class too?
e
they are methods of
Any
, which every type inherits
similarly you have
val name: String
and
val id: Int
on the
sealed class
in the example you pasted above, so those are available even if the implementation is hidden
but
copy
only exists on the
data class
which isn't accessible, so the method isn't accessible either
the
sealed class
+
private
impl is an easy hack but it has its failings (e.g.
toString
uses the wrong name,
component1
etc. functions aren't accessible meaning no destructuring)
if you really need to prevent
copy
, I would either manually write the POJO
Copy code
class User private constructor(val name: String, val id: Int) {
    override fun equals(other: Any?): Boolean = other is User && name == other.name && id == other.id
    override fun hashCode(): Int = name.hashCode() * 31 + int.hashCode()
    override fun toString(): String = "User(name=$name, id=$id)"

    operator fun component1(): String = name
    operator fun component2(): Int = id

    companion object {
        fun of(name: String, id: Int): User = User(name.ifEmpty { "Unknown" }, id)
    }
}
or use one of the plugins I mentioned previously
u
they are methods of
Any
, which every type inherits
Oh That’s what I overlooked. Thanks!