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コードでそれを行う方法がわかりません。

私はscala2.9.2を使用しています。誰かがこれについて私を助けることができますか?

4

3 に答える 3

5

特性がまったく複雑な場合は、Scalaに処理させるのが最善です。Javaがインスタンス化できるスタブをScalaに記述します。

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

コンパイルして、クラスパス上のコンパイル済みのDeps1、Deps2、およびTestClassと、次のようなscala-libraryjarを使用して実行します。javac -classpath .:scala-library.jar Test.java

于 2012-07-12T05:56:34.597 に答える
0

あなたは、Java混合特性で匿名クラスを作成する方法について質問しています。Javaでは特性を混在させることはできず、コードを含まないインターフェースを実装できるため、これは単純に不可能です。

Scala Traitの概念と、Javaとの互換性を維持しながらJVMの有効なbytecoteの上に実装する方法について少し推論すると、自分で理解できます(これは、Scalaが特性を処理する正確な方法ではありません) 、しかし非常に似ています)

  • Javaインターフェイスが作成されます
  • トレイトがクラスに混在している場合、コンパイル時に「具象」関数がコンパイラによってクラスに物理的にコピーされます。

これは、Scalaトレイトに具体的な関数を含めることを可能にするトリックですが、もちろん、ソースファイルはScalaのものである必要があります。さらに、次のような匿名クラスを作成する場合は、次のことを忘れないでください。

val a = new MyClass extends A with B

Scalaコンパイラーは、そのための匿名クラスを物理的に生成します(そして、必要な変換を適用して特性を混合します)。したがって、MyClassのインスタンスを作成する必要がある場合は、JavaからBを使用してAを拡張します。Rexが提案したように、Scalaでスタブを作成し、Javaからインスタンス化するのが最善の方法です。スタブはScalacによってコンパイルされ、Scalacは特性を正しく処理します。

于 2012-07-12T07:00:29.893 に答える