我在Scala中将trait定义为
trait checkTrait
{
val name:String = "male"
}
据我所知,当在Scala类中声明val时,只会生成访问器,但是当我使用JAD反编译器对代码进行反编译时会生成以下内容
public interface checkTrait
{
public abstract void checkTrait$_setter_$name_$eq(String s);
public abstract String name();
}
无法理解究竟是什么" checkTrait $ setter $ name_ $ eq(String s)" 是Mutator吗?如果它是Mutator,那么它们是如何生成的,因为根据语言规范,不为Vals生成Mutators
答案 0 :(得分:2)
是的,你是对的。 checkTrait$setter$name_$eq(String s)
是用于启动集name
值的 Mutator 方法。
这是由于 Scala trait 将转换为 Java接口,并且由于 Java interface
字段为{{1} },但在implicitly static and final
Scala
字段中,必须是trait
或class
的字段。所以这个 Mutator方法用于为instance
的子类初始化字段。
Java 8 (pre-release) interface member variables
完整说明:
作为反编译, Scala编译器将checkTrait
trait
转换为 Java 的checkTrait
。对于反编译,interface
中应该有另一个静态 init
方法,例如:
checkTrait
如您所见,这是一个静态init 方法,它接受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
}
实例参数。并使用值男性将 mutator方法调用checkTrait
到初始设置值。
让我们尝试checkTrait$_setter_$name_$eq
extend
:
checkTrait
和反编译此class A extends checkTrait
类:
A
我们可以发现,在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
}
的构造函数方法中,它将通过以下方式调用A
checkTrait
方法:
static init
将当前实例传递给init 5: invokestatic #28 // InterfaceMethod checkTrait.$init$:(LcheckTrait;)V
字段值。
这是 Scala 在特质中实现字段的方式。