views:

321

answers:

2

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. Recently I've been wondering how exactly traits are 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.

Could anyone explain or provide a good source explaining how traits compile to Java bytecode?

+2  A: 

Really not trying to be flip here, but have you tried using javap yet?

Ben Hardy
this gives a bit more high level overview though: http://www.codecommit.com/blog/java/interop-between-java-and-scala
Ben Hardy
I haven't tried used javap. I appreciate the link, I was hoping for a bit more detail, but it's a good starting point.
Justin Ardini
+12  A: 

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.

Mitch Blevins
Thanks! Those last 2 bits were where I was unclear. Good explanation.
Justin Ardini