MPS 2023.3 ヘルプ

MPS Java との互換性

構成

環境設定ウィンドウの Java コンパイラー構成タブには、プロジェクトのバイトコードバージョンという 1 つの設定しかありません。

JDK_Default_MPS.png

この設定は、MPS によってコンパイルされたすべての Java クラスのバイトコードバージョンを定義します。これらのクラスには、言語の側面から生成されたクラス、ランタイムソリューションのクラス、サンドボックスソリューションのクラスなどがあります。

デフォルトでは、バイトコードのバージョンは JDK Default に設定されています。これは、コンパイルされたクラスのバージョンが、MPS が実行されている Java のバージョンと同じになることを意味します。例: JDK 17 で MPS を実行し、JDK デフォルトが選択されている場合、バイトコードバージョンは 17 になります。

各モジュールは、Java タブのモジュールプロパティで Java レベルを指定できます。このようにして、選択した言語レベルの機能のみがそのモジュールの BaseLanguage コードで有効になります。

Java_compatibility.png

ビルドスクリプト

また、プロジェクトのビルドスクリプトで java 準拠レベルを設定することを忘れないでください。プロジェクトのバイトコードバージョンと同じでなければなりません。

Screen-Shot-2015-01-29-at-18-08-28.png

JDK 1.8 でコンパイルされた java クラスを使用する

MPS モジュールプールには、実行中の Java のクラスを保持する JDK ソリューションがあります。そのため、JDK 1.8 で MPS を起動すると、JDK ソリューションで最新の Java プラットフォームクラスが利用可能になります。

JDK 1.8 でコンパイルされた外部 Java クラスを Java スタブとして追加して使用することもできます。

デフォルトのインターフェースメソッド

Java 8 ではデフォルトのメソッドも導入されました。これらはインターフェースに直接実装されたメソッドです。ここでデフォルトのメソッドについて読むことができます: http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html(英語)

これらのメソッドは、通常のインスタンスメソッドとまったく同じように呼び出すことができます。ただし、クラスが実装しているインターフェースから直接デフォルトのメソッドを呼び出す必要がある場合があります。例: クラスが複数のインターフェースを実装していて、それぞれが同じシグネチャーを持つデフォルトのメソッドを含んでいるときに多重継承の場合。

public interface A {   public default void foo() {     System.out.println("A");    } } public interface B {   public default void foo() {     System.out.println("B");    } }

その場合、foo() は、jetbrains.mps.baseLanguage.jdk8 言語に新しく配置された SuperInterfaceMethodCall 構造を介して、インターフェースの 1 つで明示的に呼び出すことができます。

Screen-Shot-2015-01-29-at-20-39-29.png

jetbrains.mps.baseLanguage.jdk8 言語を使用すると、ユーザーは BaseLanguage インターフェースで 'default' メソッドを作成できます。

comx1.png

'default' キーワードは、BaseLanguage の修飾 子の概念を拡張する DefaultModifier の概念によって実装されます。

変換 / 代替メニュー + いくつかの居心地の良いインテンションも提供されています。

comx2.png
comx3.png

Java プラットフォーム API の使用

Java 8 はラムダ式を導入しました。詳細については、http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html(英語) を参照してください。

新しい JDK8 コレクション API との相互作用の例を次に示します。

Screen-Shot-2015-01-29-at-18-03-43.png

forEach() 方法java.lang.Iterable の新しいデフォルトの方法です。これは、パラメーターとしてコンシューマーインターフェースを取ります。 コンシューマーは、メソッドが 1 つしかないため、機能的なインターフェースです。Java 8 では、ラムダ式を forEach() に渡すことができます。MPS では、MPS クロージャーを渡すことができます。クロージャは、生成中に forEach() によって取得されるパラメーターの型を認識しており、コンシューマーの正しいインスタンスに対して正確に生成されます。

MPS クロージャはデフォルトで Java クラスに生成されますが、クロージャが 4 つの互換性ルールを満たしている場合、MPS はそれを Java ラムダ式に生成します。非互換性には、次の使用箇所が含まれます。

  • 歩留まり操作

  • 「機能的な」抽象クラス

  • アノテーション

  • 親スコープと競合するローカル変数

lambdas0-5.png

lambda1.png

この変更により、いくつかの問題が発生する可能性があります。

  • あいまいな呼び出し: MPS では検出されませんが、Java コンパイラーはラムダとして生成されたクロージャーに関するこのような問題を報告します。

  • Closure インスタンス: ラムダとして、クロージャは実行時に単一のインスタンスを作成します。これは、呼び出されるたびに新しいインスタンスを作成する匿名クラスとは対照的です(下のスクリーンショットを参照)。