为什么Scala伴侣对象被编译为两个类(Java和.NET编译器)?
object ScalaTrueRing { def rule = println("To rule them all") } 这段代码将被编译成java字节码,如果我反编译它,那么等效的Java代码就像这样: public final class JavaTrueRing { public static final void rule() { ScalaTrueRing..MODULE$.rule(); } } /* */ public final class JavaTrueRing$ /* */ implements ScalaObject /* */ { /* */ public static final MODULE$; /* */ /* */ static /* */ { /* */ new (); /* */ } /* */ /* */ public void rule() /* */ { /* 11 */ Predef..MODULE$.println("To rule them all"); /* */ } /* */ /* */ private JavaTrueRing$() /* */ { /* 10 */ MODULE$= this; /* */ } /* */ } 它被编译成两个类,如果我使用Scala.net编译器,它将被编译成MSIL代码,等效的C#代码是这样的: public sealed class ScalaTrueRing { public static void rule() { ScalaTrueRing$.MODULE$.rule(); } } [Symtab] public sealed class ScalaTrueRing$: ScalaObject { public static ScalaTrueRing$MODULE$; public override void rule() { Predef$.MODULE$.println("To rule them all"); } private ScalaTrueRing$() { ScalaTrueRing$.MODULE$= this; } static ScalaTrueRing$() { new ScalaTrueRing$(); } } 它也被编译成两个类. 为什么Scala编译器(用于Java的编译器和用于.NET的编译器)执行此操作? 解决方法
重要的是要理解,在scala中,对象实际上是一等公民:它是一个可以作为任何其他对象传递的实际实例.
举例: trait Greetings { def hello() { println("hello") } def bye() { println("bye") } } object FrenchGreetings extends Greetings { override def hello() { println("bonjour") } override def bye() { println("au revoir") } } def doSomething( greetings: Greetings ) { greetings.hello() println("... doing some work ...") greetings.bye() } doSomething( FrenchGreetings ) 与静态方法不同,我们的单例对象具有完整的多态性行为. doSomething确实会调用我们的重写hello和bye方法,而不是默认实现: bonjour ... doing some work ... au revoir 因此,对象实现必须是一个合适的类.但是为了与java的互操作性, public final class JavaTrueRing implements ScalaObject { public static final MODULE$; static { new JavaTrueRing(); } public void rule() { Predef.MODULE$.println("To rule them all"); } private JavaTrueRing() { MODULE$= this; } // Forwarders public static final void rule() { MODULE$.rule(); } } 我认为这不能简单的主要原因是因为在JVM中你不能在同一个类中拥有一个实例方法和一个静态方法具有相同的签名.可能还有其他原因. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |