I was just googling to find out how to create a case class with private constructor. Below is the correct way for doing this as described in
How to override apply in a case class companion
object A {
def apply(s: String, i: Int): A =
new A(s.toUpperCase, i) {} //abstract class implementation intentionally empty
}
abstract case class A private[A] (s: String, i: Int) {
private def readResolve(): Object = //to ensure validation and possible singleton-ness, must override readResolve to use explicit companion object apply method
A.apply(s, i)
def copy(s: String = s, i: Int = i): A =
A.apply(s, i)
}
Below is my understanding so far :-
If we declare a case class abstract, then implementation for copy and apply method will not be generated by the compiler.
Below is the question, that I am struggling with :-
Why it is required to provide implementation of readResolve ?
The readResolve implementation is there to prevent the creation of invalid instances of the case class by editing serialised copies of the class.
Depending on how much you trust the environment in which the code will be used, you may feel you can safely ignore this risk.
It comes about because case classes extend
Serializable
, and so may end up getting serialised and written out to file (or DB, or wherever). At this point the serialised copy in the file/DB/wherever could be edited to create an invalid value (eg. makings
lower case). On deserialising back, the 'live' instance will then be invalid, unless thereadResolve
method that is used in the deserialisation process is overriden to prevent this.