scala的trait是如何实现的?

上次讲scala基础的时候提到过特质(trait),这是一个胖接口,可以实现类似多继承的东西。

但一直很好奇这是怎么编译成class并让jvm顺利执行。

 

经过网上提问无果后,只能自己找答案了。

 

首先发现trait编译后是两个class文件,如:

 

trait TestTrait1 {
    def foo1() = {println ("foo1")};
}

 

 编译后:

TestTrait1.class和TestTrait1$class.class

经过javap -verbose后发现两个文件分别为interface和class。

TestTrait1.class(只列出关键部分)

 

public interface org.ww.test.TestTrait1 extends scala.ScalaObject
  SourceFile: "TestTrait1.scala"
。。。。。。。。。。。省略。。。。。。。。。。

{
public abstract void foo1();

}

 

 可以看出,这就是一个java的接口

 

而TestTrait1$class.class

 

public abstract class org.ww.test.TestTrait1$class extends java.lang.Object
  SourceFile: "TestTrait1.scala"
。。。。。省略。。。。。。。

{
public static void foo1(org.ww.test.TestTrait1);
  Code:
   Stack=2, Locals=1, Args_size=1
   0:   getstatic       #11; //Field scala/Predef$.MODULE$:Lscala/Predef$;
   3:   ldc     #13; //String foo1
   5:   invokevirtual   #17; //Method scala/Predef$.println:(Ljava/lang/Object;
V
   8:   return
  LineNumberTable:
   line 4: 0

  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      9      0    $this       Lorg/ww/test/TestTrait1;


public static void $init$(org.ww.test.TestTrait1);
  Code:
   Stack=0, Locals=1, Args_size=1
   0:   return
  LineNumberTable:
   line 3: 0

  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      1      0    $this       Lorg/ww/test/TestTrait1;

 

 可见,一个trait会编译成一个接口和一个实现类,而trait的实现会放在类中当做静态方法。

 

编译的时候,把实现trait的子类编译成实现trait接口的类,是实现就是调用trait静态方法

这回可以理解了吧。

 

 

 

 

慢着。。。。

好像漏了点什么。。。。

public static void $init$(TestTrait1 $this)是什么?

看名字就知道了,是在初始化实现类的时候调用trait的初始化方法,实际上就是trait的无参构造函数

 

 

到这里,关于trait在jvm的实现应该有了一个大致的了解。

对于学习scala语言来说,这种程度应该可以了,如果想有更深的了解的话,建议去看看scala的源码。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值