case class private constructor - need for readReso

2019-02-21 03:42发布

问题:

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 ?

回答1:

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. making s lower case). On deserialising back, the 'live' instance will then be invalid, unless the readResolve method that is used in the deserialisation process is overriden to prevent this.