Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why scala case class generates two apply methods?

Tags:

scala

I'm trying to explore scala case class internals a bit. To do so I'm creating simple case classes and analyzing the bytecode that scala compiler creates using javap.

I'm quite surprised to find out that when I create a case class with only one String field:

case class MyCaseClass(value: String)

the bytecode of the companion object MyCaseClass$ contains two apply methods:

  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

(compiled using scalac 2.11.6)

The first one is the one I expected - taking String as an argument and creating a new instance of my case class passing this argument to the constructor. The second one takes an object, casts it to String and then calls the first one.

I cannot think of any uses of the second method. Why is it needed? Is this behavior documented anywhere?

like image 886
Paweł Chorążyk Avatar asked May 07 '26 12:05

Paweł Chorążyk


1 Answers

The default companion object extends a function type, in this case Function1[String, MyCaseClass] (normally written as String => MyCaseClass in Scala).

The JVM signature of Function1#apply is Object apply(Object) so the overriding method must have the same signature.

like image 124
Alexey Romanov Avatar answered May 10 '26 03:05

Alexey Romanov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!