I know from this question that Scala generates for a trait
such as
trait A {
def a = { ... }
}
a structure that would look similar to the following Java code
public interface A {
public void a();
}
public class A$class {
public static void a(A self) { ... }
}
However, in Scala it is possible for a trait
to extend a class
:
class B {
def b = { ??? }
}
trait A extends B {
def a = { ??? }
}
How is this translated in a Java equivalent, where interfaces cannot inherit from classes?
Is an additional interface generated for B
?
Does this Scala feature have any impact on Java interoperability?
Well, you can just compile
and check the bytecode:
As you see
scalac
makeA
just an interface with default methods (they are available since Java 8). You might wonder, what would happen if you wanted to call someB
method inA
since we don't see thatA extends B
in bytecode:now A changed to:
As we can see the code uses
checkcast
s to castthis
toB
and then calls 'B's method - this means thatscalac
will have to make sure that then you instantiateA
it will be something that also extendsB
! So let's check what will happen when we do this:and the C is
As you can see this is very context-dependent how things end up with bytecode - the compiler will juggle things around to make it fit things in the end, but only if it will know how you use it.
Therefore if you want interoperability with Java, stick to simple
trait
s andclass
es as your common interface, and let Scala instantiate more complex implementations. Doing this yourself from Java might bite you in many unexpected ways.