Scala case 类生成了哪些方法?

What methods are generated for Scala case classes?

Scala case classes 生成了哪些方法?

我知道有些方法是专门为案例class生成的:

其他的是什么?

此外,我发现我可以在任何情况下调用 productArity() class。这是如何运作的?换句话说,为什么下面的代码有效?

case class CaseClass()

object CaseClass {
  val cc = new CaseClass()
  cc.productArity
}

的确,案例 classe 自动定义了 equalscanEqual 方法,但它也为构造函数参数定义了 getter 方法。还有一个可以调用的 toString 方法。

案例class也是Product的实例,因此继承了这些方法。这就是你调用 productArity 的原因。

在 Scala 中为特定 class 生成方法的一个好方法是使用 javap 命令。

找到由 scalac 编译的 .class 文件,然后从各自的命令行工具中找到 运行 javap -private 命令。这将向您展示 class.

的构造函数、字段和所有方法

您可以针对您的情况执行此操作 class 以查看 Scala 自动提供了哪些类型的内容。

Case classes mixin Product trait 提供了 productArity 方法。对于 class 的情况,productArity 方法将 return class 定义中提供的参数列表的计数。

给定Test.scala-

case class Test()

您可以运行 scalac Test.scala -print 准确查看生成的内容

[[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: Int): Object = {
      case <synthetic> val x1: Int = x;
      case4(){
        matchEnd3(throw new IndexOutOfBoundsException(scala.Int.box(x).toString()))
      };
      matchEnd3(x: Object){
        x
      }
    };
    override <synthetic> def productIterator(): Iterator = runtime.this.ScalaRunTime.typedProductIterator(Test.this);
    <synthetic> def canEqual(x: Object): Boolean = x.$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: Object): Boolean = {
  case <synthetic> val x1: Object = x;
  case5(){
    if (x1.$isInstanceOf[com.Test]())
      matchEnd4(true)
    else
      case6()
  };
  case6(){
    matchEnd4(false)
  };
  matchEnd4(x: Boolean){
    x
  }
}.&&(x.$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[=10=]: com.Test): Boolean = if (x[=10=].==(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>();
      ()
    }
  }
}