1

我正在开发一个同时具有 scala 和 java 代码的项目。我想在java代码中使用用scala编写的类。我遇到的问题是 scala 类有一些自类型依赖项。从java创建该类的新实例时,我不知道如何给它们。

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。谁可以帮我这个事?

4

3 回答 3

5

如果特征非常复杂,最好让 Scala 处理它们。在 Scala 中编写一个 Java 可以实例化的存根:

class TestWithDeps extends TestClass with Deps1 with Deps2
于 2012-07-12T05:59:21.887 回答
1

Scala 特征被编译为 Java 接口。因此,例如,在您的 Java 代码中,您正在实现接口 Deps1。有关示例和详细信息,请参见此答案

对于您的代码,以下 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

像这样在类路径和 scala-library jar 上编译并运行已编译的 Deps1、Deps2 和 TestClassjavac -classpath .:scala-library.jar Test.java

于 2012-07-12T05:56:34.597 回答
0

您正在询问如何在 Java 混合特征中创建匿名类。这根本不可能,因为在 Java 中你不能混合一个 trait,你可以实现一个不包含代码的接口。

如果您对 Scala Trait 的概念以及如何在 JVM 有效字节码之上实现它以保持与 Java 的兼容性进行一些推理,那么您自己会弄清楚(我并不是说这是 Scala 对待特征的确切方式, 但非常相似)

  • 创建一个java接口
  • 当特征混合到一个类中时,在编译时“具体”函数被编译器物理复制到类中。

这是允许 Scala trait 包含具体函数的技巧,但当然您需要源文件是 Scala 文件。此外请记住,当您创建匿名类时,例如:

val a = new MyClass extends A with B

scala 编译器为此物理生成一个匿名类(并应用必要的转换来混合特征)。因此,如果您需要从 Java 创建 MyClass 的实例 extends A with B,正如 Rex 建议的那样,最好的方法是在 Scala 中创建一个存根,并从 Java 实例化它。存根将由 Scalac 编译,它将正确处理 trait。

于 2012-07-12T07:00:29.893 回答