2012-07-12 68 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编译,这将正确处理特征。