【问题标题】:Why scala case class generates two apply methods?为什么scala case类生成两个apply方法?
【发布时间】:2018-07-18 17:27:32
【问题描述】:

我正在尝试探索一下 scala 案例类的内部结构。为此,我正在创建简单的案例类并分析 scala 编译器使用 javap 创建的字节码。

我很惊讶地发现,当我创建一个只有一个字符串字段的案例类时:

case class MyCaseClass(value: String)

伴随对象MyCaseClass$的字节码包含两个apply方法:

  public MyCaseClass apply(java.lang.String);
    Code:
       0: new           #23                 // class MyCaseClass
       3: dup
       4: aload_1
       5: invokespecial #26                 // Method MyCaseClass."<init>":(Ljava/lang/String;)V
       8: areturn

  public java.lang.Object apply(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #53                 // class java/lang/String
       5: invokevirtual #55                 // Method apply:(Ljava/lang/String;)LMyCaseClass;
       8: areturn

(使用 scalac 2.11.6 编译)

第一个是我所期望的 - 将 String 作为参数并创建我的案例类的新实例,将此参数传递给构造函数。第二个接受一个对象,将其转换为 String,然后调用第一个。

我想不出第二种方法的任何用途。为什么需要它?这种行为是否记录在任何地方?

【问题讨论】:

    标签: scala


    【解决方案1】:

    默认伴随对象扩展了一个函数类型,在本例中为Function1[String, MyCaseClass](在Scala 中通常写为String =&gt; MyCaseClass)。

    Function1#apply 的 JVM 签名是 Object apply(Object),因此覆盖方法必须具有相同的签名。

    【讨论】:

    猜你喜欢
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    • 2018-08-04
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多