在Scala Trait中使用Val

时间:2017-04-17 06:37:56

标签: scala

我在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

1 个答案:

答案 0 :(得分:2)

是的,你是对的。 checkTrait$setter$name_$eq(String s)是用于启动集name值的 Mutator 方法。

这是由于 Scala trait 将转换为 Java接口,并且由于 Java interface字段为{{1} },但在implicitly static and final Scala字段中,必须是traitclass的字段。所以这个 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 特质中实现字段的方式。