28

Java7のランタイム機能はJava6では使用できないことは承知していますが、新しいバイトコードが追加されていないため、新しいバイトコードinvokedynamicはJava以外の言語にのみ関連するため、Javaを変換するのはどれほど難しいのでしょうか。 7ソースコード(新しいswitchステートメント、ダイヤモンド演算子)を純粋なJava 6に(つまり、Java6の互換性を失うことなくソースをJava7に変換し始めることができるようにするため)。

ポインタはありますか?

4

4 に答える 4

11

私の知る限り、現時点ではこの問題の解決策はありません。最善の策は、Java1.7コンストラクトを処理するためにretrotranslatorを拡張することです。ダイヤモンド演算子は、バイトコードの変更をまったく必要としないため、非常に簡単です。

「新しいバイトコードは追加されていません」という記述は正しくありません。新しいinvokedynamicバイトコードがあり、さらに重要なことに、生成されたバイトコードが1.6 JREで有効にならない場合があるため、レトロトランスレーターはそれを修正する必要があります。

于 2011-10-05T13:54:39.517 に答える
7

Java 7 javacによって出力された.classファイルをバージョン1.6.0(つまり、0x32)でマークします。

printf "\ x00 \ x00 \ x00 \ x32" | dd of = Example.class seek = 4 bs = 1 count = 4 conv = notrunc

http://en.wikipedia.org/wiki/Java_class_file#General_layoutによる)

これを(ファイル名に$ 1を使用して)入れると、j6patchすべてのクラスファイルを次のように実行できます。

探す 。-name\*。class|xargs -I {} ./j6patch {}

私はこれを大規模な(〜4.8 MB jar)コードベースで使用RetroTranslatorし、java 6 jarでも使用したため、Java5で実行されるアプリでJava7言語機能を使用できます。また、Java 7コンパイラ(javac)は多くの追加機能を実行します。パフォーマンスを大幅に向上させる最適化(エスケープ分析など)。

RetroTranslatorwith-verify -target 1.5およびJRE1.6ランタイムjarを使用すると、Java7ランタイム機能が使用されていないことを確認できます。

于 2013-08-21T22:14:55.903 に答える
3

あなたは、invokedynamic命令がJavaによって使用されていないことは正しいですが、Javaで使用できる他のいくつかの関連する変更があります。Invokedynamicは、invokevirtual命令にもいくつかの変更が加えられた新しい「動的リンケージメカニズム-メソッドハンドル」に依存しています。詳細については、この記事の「新しい動的リンケージメカニズム:メソッドハンドル」のセクションを参照してください。

メソッドハンドルは、リフレクションのより高速な代替手段も提供するため、Javaで役立ちます。この機能はJava7VMに依存しているため、メソッドハンドルを使用してコードをJava6に変換することはできません。

于 2011-10-06T03:30:07.237 に答える
2

おそらくいくつかの作業ですが、これを試してください:

EclipseのJavaコンパイラをクラスパスに追加します。プラグインにあります(フォルダでorg.eclipse.jdt.core検索してください)。org.eclipse.jdt.core_*.jarplugins

このJARには、コンパイラーとパーサーが含まれています。自分でパーサーを呼び出してから、を使用しASTVisitorて解析ツリーをトラバースできます。

次に、ツリーを変更し、これから新しいソースコードを作成して、通常どおりにコンパイルできます。

コンパイラがバイトコードを生成する前に、ASTツリーを「前処理」することさえ可能かもしれません。これにより、「ソースをディスクに書き戻し、そこからコンパイルする」手順を節約できます。

于 2012-04-05T12:41:35.953 に答える