FAQ - Javaとの相互運用性

    1. ScalaがJavaと互換性があるというのは何を意味していますか?

    2. Java 1.5のジェネリクスはScalaから使えますか?

    3. ScalaからJavaへの変換について、どこを読めばわかりますか?

    4. 既存のJavaコードをScalaから使えますか?

    5. Javaのデータ構造をScalaのものに変換したり、その逆をしたりする必要はありますか?

    6. ScalaコードをJavaソースにコンパイルできますか?(たとえば、GWTは使えますか?)

    7. 何故、クラスYから継承した、protected staticなインナークラスXにアクセスしようとすると、"error: class X cannot be accessed in object Y"というメッセージが出てコンパイルに失敗するのですか?

ScalaがJavaと互換性があるというのは何を意味していますか?

Scalaの標準的なバックエンドはJava VMです。ScalaのクラスはJavaのクラスでもあり、その逆も成り立ちます。ScalaからJavaのメソッドを呼び出すことも、その逆もできます。ScalaのクラスをJavaのクラスから継承することやその逆も出来ます。主な制限は、いくつかのScalaの機能は、同様のものがJavaには無い点です。たとえば、トレイトはJavaにはありません。

Java 1.5のジェネリクスはScalaから使えますか?

Scala 2.7.0から、JavaのジェネリクスがScalaプログラムから見えるようになりました。Scala 2.7.2からは、ScalaジェネリクスがJavaプログラムから見えるようになりました。しかし、高階型パラメータはJavaプログラムから利用することはできません。

ScalaからJavaへの変換について、どこを読めばわかりますか?

現在は文書化されていません。しかしながら、一般的には、ScalaはJavaと互換性があるように設計されており、Javaの同様の機能にマッピングするように努めています。たとえば、Scalaクラスは同じ名前のJavaクラスになる、などです。しかし、より正確な情報を知りたければ、javapのようなツールを使うしか無いでしょう。

既存のJavaコードをScalaから使えますか?

ScalaコードからJavaのクラスにアクセスすることには何の問題もありません。ScalaのクラスをJavaから使うのはトリッキーな事になることがあります。特に、Scalaクラスがジェネリックスや多相メソッド、抽象型などを使っている場合などです。Javaはそのような言語機能を持っていないので、ScalaクラスがどのようにしてJavaクラスにエンコーディングされるかを知る必要があります。それ以外の場合は、問題ありません。

Javaのデータ構造をScalaのものに変換したり、その逆をしたりする必要はありますか?

Scalaで使うために、Javaのデータ構造を変換する必要はまったくありません。Javaのデータ構造は、「そのまま」使う事ができます。たとえば、Scalaクラスを継承してJavaのクラスを作ることができますし、ScalaからJavaのクラスのインスタンスを生成できますし、メソッドやフィールドにアクセスすることもできます(例えそれがstaticであったとしても)、などなど。

ScalaコードをJavaソースにコンパイルできますか?(たとえば、GWTは使えますか?)

現在は出来ません。しかし、そのような機能を提供しようというプロジェクトが進行中です。

何故、クラスYから継承した、protected staticなインナークラスXにアクセスしようとすると、"error: class X cannot be accessed in object Y"というメッセージが出てコンパイルに失敗するのですか?

これはScalaのよく知られた制限です。Scalaには「staticな」メンバという概念が存在しません。代わりに、ScalaはクラスYのstaticメンバを、シングルトンオブジェクトY(クラスYのコンパニオンオブジェクト)のメンバのようにみなします。このようなクラスから継承するとき、クラスYのprotectedメンバにだけアクセスすることができ、シングルトンオブジェクトYのprotectedメンバにはアクセスすることができません。

Scalaにおいて、static protectedを、Scalaのオブジェクトモデルを損なうこと無しにシミュレートすることは根本的にできません。ですので、これを変更するわけにはいきません。この制限を回避するには、protected staticなインナークラスへの全てのアクセスをカプセル化した、エンクロージングクラスの実装をJavaで書く必要があります。

より詳細な情報および、具体的な制限と回避方法については、チケット #1806 を参照してください。