Search code examples
scalabytecode

How are Scala traits compiled into Java bytecode?


I have played around with Scala for a while now, and I know that traits can act as the Scala equivalent of both interfaces and abstract classes. How exactly are traits compiled into Java bytecode?

I found some short explanations that stated traits are compiled exactly like Java interfaces when possible, and interfaces with an additional class otherwise. I still don't understand, however, how Scala achieves class linearization, a feature not available in Java.

Is there a good source explaining how traits compile to Java bytecode?


Solution

  • I'm not an expert, but here is my understanding:

    Traits are compiled into an interface and corresponding class.

    trait Foo {
      def bar = { println("bar!") }
    }
    

    becomes the equivalent of...

    public interface Foo {
      public void bar();
    }
    
    public class Foo$class {
      public static void bar(Foo self) { println("bar!"); }
    }
    

    Which leaves the question: How does the static bar method in Foo$class get called? This magic is done by the compiler in the class that the Foo trait is mixed into.

    class Baz extends Foo
    

    becomes something like...

    public class Baz implements Foo {
      public void bar() { Foo$class.bar(this); }
    }
    

    Class linearization just implements the appropriate version of the method (calling the static method in the Xxxx$class class) according to the linearization rules defined in the language specification.