26

既存のJavaアプリにScalaコードを挿入しようとしています。(だから、言われているように、私はもう少し楽しみたいです)。

Scalaでシングルトンのものを作成します

ScalaPower.scala

    package org.fun
    class ScalaPower
    object ScalaPower{
      def showMyPower(time:Int) = {
        (0 to time-1).mkString(", ")
      }
    }

さて、OldJava.java内

class OldJava {
  public void demo(){
    System.out.println(?)
  }
}

?JavaがshowMyPowerメソッドを呼び出すようにするには、何を入力する必要がありますか?org.fun.ScalaPower.showMyPower(10)私は両方を試しまし org.fun.ScalaPower.getInstance().showMyPower(10)たが、うまくいきませんでした。

(Jadを使用してクラスファイルを逆コンパイルすると、意味のないコードしか表示されません。)

編集 私は宣言を削除しclass ScalaPower、scalaは期待どおりに静的メソッドを生成します。(ただ動作するように呼び出しますorg.fun.ScalaPower.showMyPower(10))。

それがscalaコンパイラのバグかどうか疑問に思う

4

5 に答える 5

22

通常は、独自のクラスからシングルトンに直接アクセスする方が適切です。

この場合:

org.fun.ScalaPower$.MODULE$.showMyPower(10);

実装の詳細にはあまり触れずに、Scala はオブジェクトとクラス/トレイトの間で名前空間を区別します。これは、同じ名前を使用できることを意味します。ただし、オブジェクトにはクラスがあるため、JVM ではマングル名が必要です。現在の Scala の規則では、モジュール名の末尾に $ を追加します (トップレベル モジュールの場合)。オブジェクトがクラスで定義されている場合、規約は OuterClass$ModuleName$ であると思います。ScalaPower モジュールのシングルトン プロパティを強制するために、ModuleName$ クラスの静的な MODULE$ メンバーもあります。これは、クラスのロード時に初期化され、インスタンスが 1 つだけになるようにします。これの副作用は、モジュールのコンストラクターでいかなる種類のロックも行うべきではないということです。

いずれにせよ、Scala には「Java をより便利にする」ための静的フォワーダー メカニズムも組み込まれています。これは、ScalaPower$.MODULE$.someMethod() を呼び出すだけの ScalaPower クラスの静的メソッドを記述する場所です。コンパニオン クラスも定義する場合、生成できるフォワーダーは制限されます。これは、JVM 上の静的およびインスタンス レベルのメソッドとの名前の競合が許可されていないためです。2.8.0 では、これは、コンパニオン オブジェクトがある場合、静的フォワーダーが失われることを意味すると思います。

この場合、"ベスト プラクティス" は、静的フォワーダーの代わりに常に ScalaPower$.MODULE$ 参照を使用することです。これは、フォワーダーが ScalaPower クラスへの変更で消える可能性があるためです。

編集:タイプミス

于 2010-08-10T02:22:31.790 に答える
10

これは間接的にそれをカバーしていると思います:

コンパニオン オブジェクトと Java 静的メソッド

コンパニオン オブジェクトについて知っておくべきことがもう 1 つあります。アプリケーションのエントリ ポイントとして使用するメイン メソッドを定義するときはいつでも、Scala はそれをオブジェクトに配置する必要があります。ただし、この記事の執筆時点では、メイン メソッドをコンパニオン オブジェクトで定義することはできません。生成されたコードの実装の詳細のため、JVM は main メソッドを見つけられません。この問題は、将来のリリースで解決される可能性があります。今のところ、シングルトン オブジェクト (つまり、「非コンパニオン」オブジェクト) でメイン メソッドを定義する必要があります [ScalaTips]。main を定義しようとする単純な Person クラスとコンパニオン オブジェクトの次の例を考えてみましょう。

ここにあるように:http://programming-scala.labs.oreilly.com/ch06.html

つまり、オブジェクトはコンパニオン オブジェクト (コンパニオン クラスを持っている) であるため、期待どおりに呼び出すことはできません。あなたがクラスを取り除くならば、それはうまくいくでしょう。

于 2010-07-20T14:56:52.710 に答える
10

どのようなエラーが表示されましたか? Scala サンプルと次の Java クラスを使用します。

cat test.java:


import org.fun.*;

public class test {
    public static void main(String args[]) {
       System.out.println("show my power: " + ScalaPower.showMyPower(3));       
    }
}

そして、次のように実行します。

java -cp .:<path-to/scala/install-dir>/lib/scala-library.jar test

私の出力を与えます:

show my power: 0, 1, 2

于 2010-07-19T16:45:13.817 に答える
3

ストックjavapツールを使用して、Scala コンパイラが生成するものを確認できることに注意してください。もちろん、あなたの質問に直接答えるわけではありませんが、コード生成パターンを思い出すだけで十分な場合は、それで十分です。

于 2010-07-19T16:13:41.767 に答える
1

した後

class ScalaPower 
object ScalaPower{
  def showMyPower(time:Int) = {
    (0 to time-1).mkString(", ")
  }
}

ScalaPower.showMyPower(10)期待どおりに動作します。

于 2010-08-09T21:03:59.723 に答える