Reputation: 464
What methods are generated for Scala case classes?
I know that some methods are generated specifically for case classes:
What are the others?
Also, I see that I can call productArity() on any case class. How does this work? In other words, why the following code is valid?
case class CaseClass()
object CaseClass {
val cc = new CaseClass()
cc.productArity
}
Upvotes: 2
Views: 2854
Reputation: 7348
Given Test.scala -
case class Test()
You can run scalac Test.scala -print
to see exactly what's generated
[[syntax trees at end of cleanup]] // Test.scala
package com {
case class Test extends Object with Product with Serializable {
<synthetic> def copy(): com.Test = new com.Test();
override <synthetic> def productPrefix(): String = "Test";
<synthetic> def productArity(): Int = 0;
<synthetic> def productElement(x$1: Int): Object = {
case <synthetic> val x1: Int = x$1;
case4(){
matchEnd3(throw new IndexOutOfBoundsException(scala.Int.box(x$1).toString()))
};
matchEnd3(x: Object){
x
}
};
override <synthetic> def productIterator(): Iterator = runtime.this.ScalaRunTime.typedProductIterator(Test.this);
<synthetic> def canEqual(x$1: Object): Boolean = x$1.$isInstanceOf[com.Test]();
override <synthetic> def hashCode(): Int = ScalaRunTime.this._hashCode(Test.this);
override <synthetic> def toString(): String = ScalaRunTime.this._toString(Test.this);
override <synthetic> def equals(x$1: Object): Boolean = {
case <synthetic> val x1: Object = x$1;
case5(){
if (x1.$isInstanceOf[com.Test]())
matchEnd4(true)
else
case6()
};
case6(){
matchEnd4(false)
};
matchEnd4(x: Boolean){
x
}
}.&&(x$1.$asInstanceOf[com.Test]().canEqual(Test.this));
def <init>(): com.Test = {
Test.super.<init>();
scala.Product$class./*Product$class*/$init$(Test.this);
()
}
};
<synthetic> object Test extends scala.runtime.AbstractFunction0 with Serializable {
final override <synthetic> def toString(): String = "Test";
case <synthetic> def apply(): com.Test = new com.Test();
case <synthetic> def unapply(x$0: com.Test): Boolean = if (x$0.==(null))
false
else
true;
<synthetic> private def readResolve(): Object = com.this.Test;
case <synthetic> <bridge> <artifact> def apply(): Object = Test.this.apply();
def <init>(): com.Test.type = {
Test.super.<init>();
()
}
}
}
Upvotes: 4
Reputation: 2095
A good way what methods are generated for a specific class in Scala is to use the javap
command.
Find the .class file that was compiled by scalac
and then run the javap -private
command on it from your respective command line tool. This will show you the constructors, fields, and all methods for a class.
You can do this for your case class to see what kinds of things are automagically supplied by Scala.
Case classes mixin the Product
trait which provides the productArity
method. For case classes the productArity
method will return the count of the parameter list supplied in the class definition.
Upvotes: 4
Reputation: 2937
It's true that a case classe automatically define equals
and canEqual
methods but it's also define getter
methods for the constructor arguments. There's also a toString
method that you can call.
A case class is also an instance of Product
and thus inherit these methods. This is why you call productArity.
Upvotes: 1