FAQ - Javaとの相互運用性
ScalaがJavaと互換性があるというのは何を意味していますか?
Java 1.5のジェネリクスはScalaから使えますか?
ScalaからJavaへの変換について、どこを読めばわかりますか?
既存のJavaコードをScalaから使えますか?
Javaのデータ構造をScalaのものに変換したり、その逆をしたりする必要はありますか?
ScalaコードをJavaソースにコンパイルできますか?(たとえば、GWTは使えますか?)
何故、クラス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 を参照してください。