Scala Class and Object disassembled

A Scala Class translates into an equivalent Java Class implementing scala.ScalaObject:

In Scala:

class TestScalaClass

if disassembled produces the following equivalent Java code:

public class TestScalaClass extends java.lang.Object implements scala.ScalaObject{
    public TestScalaClass();
}

The Scala Object which is Scala’s in-language support for Singleton Pattern:

object TestScalaObject

compiles into two bytecode files: TestScalaObject.class and TestScalaObject$.class.

TestScalaObject.class disassembles into:

public final class TestScalaObject extends java.lang.Object{
}

whereas TestScalaObject$.class disassembles into:

public final class TestScalaObject$ extends java.lang.Object implements scala.ScalaObject{
    public static final TestScalaObject$ MODULE$;
    public static {};
}

MODULE$ makes Scala to be accessible through Java.

Scala advanced Type Inference

Scala is a statically typed JVM language which means that the variable types are defined at compile time. This is the case also for Java and C++ although the advanced type inference system in Scala let the language behave and ‘feel’ like a dynamic language although the compiler is still doing all the hard work of figuring out the variable type.

Consider the following examples in Java and Scala that produce identical compile code in the bytecode level.

Java code:

class TestTypeInferenceJava {

        public static void main(String[] args){
                int x=10;
        }
}

which after desassembling:

javap -c TestTypeInferenceJava

produces the following bytecode:

Compiled from "TestTypeInferenceJava.java"
class TestTypeInferenceJava extends java.lang.Object{
TestTypeInferenceJava();
  Code:
   0:	aload_0
   1:	invokespecial	#1; //Method java/lang/Object."<init>":()V
   4:	return

public static void main(java.lang.String[]);
  Code:
   0:	bipush	10
   2:	istore_1
   3:	return

}

Note the bipush opcode that pushes the integer into the stack as well as the istore_1 that stores the integer into the stack as a local variable.

The equivalent Scala code is:

class TestTypeInference {
        def main(args: Array[String]): Unit = {
                var x=10
        }
}

that disassembles into:

public class TestTypeInference extends java.lang.Object implements scala.ScalaObject{
public void main(java.lang.String[]);
  Code:
   0:	bipush	10
   2:	istore_2
   3:	return

public TestTypeInference();
  Code:
   0:	aload_0
   1:	invokespecial	#19; //Method java/lang/Object."<init>":()V
   4:	return

}

Note the type inference of the integer variable (bipush and istore_1) as well as the identically produced bytecode (only discrepancy is the difference in the index of the corresponding local variable).