ilinum
ilinum

Reputation: 464

What methods are generated for Scala case classes?

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

Answers (3)

Maxim
Maxim

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

nattyddubbs
nattyddubbs

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

alifirat
alifirat

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

Related Questions