How to create varargs apply function

Yes, they are merged, but there’s a special rule - if there’s an explicitly defined method then compiler doesn’t provide its own generated definition. So e.g. case class X(a: Int, b: String) expands to:

class X(val a: Int, val b: String) {
  def equals ...
  def hashCode ...
  def toString ...
  ...
}
object X {
  def apply(a: Int, b: String): X = X(a, b)
  def unapply ...
}

but if you e.g. provide your own toString then your implementation won’t be replaced by autogenerated one:

case class X(a: Int, b: String) {
  override def toString(): String =
    "hey, this method is explicitly defined so compiler won't regenerate it!"
}

This rule applies to both class and it’s companion object.

We’ve already used that rule here: What does Equivalence of instances mean? - #11 by tarsa to provide own equals and hashCode definitions instead of the auto-generated ones.

If you look at generated .class files then you’ll notice that object Xxx compiles to two files: Xxx.class and Xxx$.class. OTOH class Xxx compiles to just Xxx.class. So every time you have a class (no matter if case or not) with its companion object the Xxx.class contains definitions related to both class and object. In other words - merging happens quite often.

1 Like