2011-10-19 70 views
11

在Scala中,我們可以寫什麼是Scala對象的Java等價物?

object Foo { def bar = {} } 

這是如何由編譯器實現?我能夠從Java 但new Foo();從Java調用Foo.bar();給出了錯誤cannot find symbol symbol: constructor Foo()

  • 是否JVM支持單身本身?
  • 是否有可能在Java中沒有構造函數的類?

注:此處是scalac -print

package <empty> { 
    final class Foo extends java.lang.Object with ScalaObject { 
    def bar(): Unit =(); 
    def this(): object Foo = { 
     Foo.super.this(); 
    () 
    } 
    } 
} 

回答

11

支持單身輸出代碼不在一個語言水平,但語言提供了足夠的設施沒有任何麻煩來創建它們。

考慮下面的代碼:

public class Singleton { 
    private static final Singleton instance = new Singleton(); 

    // Private constructor prevents instantiation from other classes 
    private Singleton() {} 

    public static Singleton getInstance() { 
     return instance; 
    } 
} 

這是維基百科,這也解釋了一個單如何能做出了表率。一個實例保存在一個專用字段中,構造函數在類之外是不可訪問的,該方法返回這個單一實例。

至於構造函數:每類默認情況下,有一個所謂的默認構造函數它沒有參數,只是調用父類的無參數的構造函數。如果超類沒有任何沒有參數的可訪問構造函數,則必須編寫一個顯式構造函數。

所以一個類必須有一個構造函數,但如果超類具有無參數構造函數,則不必編寫它。

+0

啊等等的技巧是使構造私有。 – Jus12

21

當編譯代碼,Scala編譯器生成以下Java代碼的等效:

public final class Foo { 
    private Foo() {} // Actually, Foo doesn't have constructor at all 
        // It can be represented in bytecode, 
        // but it cannot be represented in Java language 

    public static final void bar() { 
     Foo$.MODULE$.bar(); 
    } 
} 

public final class Foo$ implements ScalaObject { 
    public static final Foo$ MODULE$; 
    static { 
     new Foo$(); 
    } 
    private Foo$() { MODULE$ = this; } 
    public final void bar() { 
     // actual implementation of bar() 
    } 
} 

這裏Foo$是實際實現一個單身的,而Foo提供了與Java交互的static方法。

+0

有沒有什麼辦法可以看到「中間」的Java代碼?你使用反編譯器來生成它嗎? – Jus12

+1

@ Jus12:也許有些反編譯器能夠顯示它,但是我從'javap -c -private Foo' /'javap -c -private Foo $'的輸出手動重構了它, – axtavt

相關問題