Reputation: 357
I defined trait in Scala as
trait checkTrait
{
val name:String = "male"
}
As i understand when val are declared in Scala Class only accessors are generated but when i decompiled above code using JAD decompiler following gets generated
public interface checkTrait
{
public abstract void checkTrait$_setter_$name_$eq(String s);
public abstract String name();
}
Not able to understand what exactly is "checkTrait$setter$name_$eq(String s)" is it Mutator? If it is Mutator then how they are getting generated, because as per language specification Mutators are not generated for Vals
Upvotes: 2
Views: 553
Reputation: 14227
Yes, You are right. checkTrait$setter$name_$eq(String s)
is a Mutator method for initing set name
value.
This is caused of Scala trait will convert to Java interface, and Since Java interface
fields is implicitly static and final
, but in Scala
trait
field need to be an field of class
or instance
. so this Mutator method is used to init the field for checkTrait
's subclass.
Java 8 (pre-release) interface member variables
Full Explanation:
As your decompilation, Scala Compiler convert trait
checkTrait
to Java's interface
. and for this decompilation should have another static init
method in checkTrait
, like:
public interface checkTrait {
public abstract void checkTrait$_setter_$name_$eq(java.lang.String);
public abstract java.lang.String name();
public static void $init$(checkTrait);
Code:
1: ldc #18 // String male
3: invokeinterface #20, 2 // InterfaceMethod checkTrait$_setter_$name_$eq:(Ljava/lang/String;)V
8: return
}
As you can see, this is a static init method with accepting a checkTrait
instance parameter. and invoke checkTrait$_setter_$name_$eq
this mutator method to initial set value with value: male.
Let us try to extend
checkTrait
:
class A extends checkTrait
and decompile this A
class:
public class A implements checkTrait {
public java.lang.String name();
Code:
0: aload_0
1: getfield #15 // Field name:Ljava/lang/String;
4: areturn
public void checkTrait$_setter_$name_$eq(java.lang.String);
Code:
0: aload_0
1: aload_1
2: putfield #15 // Field name:Ljava/lang/String;
5: return
public A();
Code:
0: aload_0
1: invokespecial #24 // Method java/lang/Object."<init>":()V
4: aload_0
5: invokestatic #28 // InterfaceMethod checkTrait.$init$:(LcheckTrait;)V
8: return
}
And we can find, In the A
's constructor method, it will invoke the checkTrait
static init
method by:
5: invokestatic #28 // InterfaceMethod checkTrait.$init$:(LcheckTrait;)V
with pass current instance to init name
field value.
So that's Scala way of implementing a field in trait.
Upvotes: 2