2012-07-12 72 views
0

我正在研究一個同時具有scala和java代碼的項目。我想在java代碼中使用用scala編寫的類。我遇到的問題是scala類有一些自我類型依賴關係。從java中創建該類的新實例時,我不知道如何給它們。從java初始化自我類型依賴關係的scala類

trait Deps1 { 
def dep1 = println("dep1") 
} 

trait Deps2 { 
def dep2 = println("dep2") 
} 

class TestClass { 
this: Deps1 with Deps2 => 

def test = { 
    dep1 
    dep2 
} 
} 

Scala中,如果我創造的TestClass比如我可以用new TestClass with Deps1 with Deps2,但我不知道該怎麼做,在Java代碼。

我使用的是scala 2.9.2。誰可以幫我這個事?

+0

我建議使用'javap'來理解從這個Scala源生成的'.class'文件。我懷疑你會發現從Java開始工作太麻煩。 – mergeconflict 2012-07-12 05:36:32

+0

根據Brain和Rex的回答,有兩種主要方法可以實現此功能。
方法1:
在scala中創建具有所有依賴關係的類並使用它(如Rex所述)是我認爲的最簡單的方法。
方法2:
除此之外,我們可以按如下方式直接在java中實現類並使用它。
class TestClassWithDeps extends TestClass implements Deps1,Deps2 Deps1 $ class.dep1(this);這個函數返回的值爲0。 \t} \t公共無效DEP2(){ \t \t Deps2 $ class.dep2(本); \t} } – 2012-07-12 07:10:56

回答

5

如果特性非常複雜,那麼最好讓Scala處理它們。在Java中可以瞬間寫出Scala中的存根:

class TestWithDeps extends TestClass with Deps1 with Deps2 
+1

絕對比在java端實現它更好 – 2012-07-12 06:53:47

1

斯卡拉特徵被編譯爲Java接口。因此,在您的Java代碼中,您正在實現Deps1接口。請參見本answer例如,並詳細介紹

爲您的代碼的Java代碼的工作原理:

class Test extends TestClass implements Deps1, Deps2{ 
    public void dep1(){ 
    Deps1$class.dep1(this); 
    } 

    public void dep2(){ 
    Deps2$class.dep2(this); 
    } 

    public static void main(String []args){ 
    Test test = new Test(); 
    test.dep1(); 
    test.dep2(); 
    } 

} 

運行這給:

dep1 
dep2 

編譯和編譯Deps1,Deps2運行,類路徑上的TestClass和scala-library jar如此javac -classpath .:scala-library.jar Test.java

+0

通過這種方式,我必須在側面'Test'類中實現dep1和dep2方法的邏輯。 – 2012-07-12 06:44:45

+1

通過Brain給出的鏈接後,我們可以調用'Deps1 $ class.dep1(this);''dep1'方法內部,所以我們可以執行scala特徵的dep1方法。所以不需要重新實現邏輯。 – 2012-07-12 07:19:48

0

您在問如何在Java混合特徵中創建匿名類。這是不可能的,因爲在Java中你不能混合一個特性,你可以實現一個不包含代碼的接口。

如果你理解了一點關於Scala Trait的概念,以及它如何在JVM的頂部實現有效的守護進程,保持與Java的兼容性,你可以自己弄明白(我不是說這是確切的方式的Scala對待性狀,但很相似)

  • Java接口創建
  • 當性狀混入類,在編譯時「混凝土」功能在物理上由編譯器複製到類。

這是允許Scala trait包含具體函數的技巧,但當然你需要源文件是Scala。還記得當你創建了匿名類:

val a = new MyClass extends A with B 

Scala編譯器生成的物理爲匿名類(並應用必要的改造,以混合的特徵)。所以,如果你需要用Java創建MyClass extends A和B的實例,Rex建議最好的方法是在Scala中創建一個存根,並從Java實例化。該存根將由Scalac編譯,這將正確處理特徵。