1. ホーム
  2. java

[解決済み] Java言語では利用できないバイトコード機能

2022-04-28 01:55:47

質問

現在(Java 6)、Javaバイトコードでできることで、Java言語内からできないことはありますか?

どちらもチューリングコンプリートだと思いますが、"can do" を "can do significantly faster/better, or just in the different way" と読み替えてください。

私が考えているのは、以下のような余分なバイトコードです。 invokedynamic その特定のものが将来のバージョンであることを除いて、Javaを使って生成することはできません。

解決方法は?

私の知る限り、Java 6でサポートされるバイトコードには、Javaのソースコードからもアクセスできないような主要な機能は存在しません。その主な理由は、明らかに、JavaバイトコードがJava言語を念頭に置いて設計されているからです。

しかし、最新のJavaコンパイラでは生成されない機能もあります。

  • ACC_SUPER フラグ :

    これは、クラスに設定可能なフラグで、特定のコーナーケースの invokespecial のバイトコードは、このクラスで処理されます。これは、すべてのモダンなJavaコンパイラ(私の記憶が正しければ、 "modern"は >= Java 1.1 )によって設定され、古いJavaコンパイラだけがこれが設定されていないクラスファイルを作成しました。このフラグは後方互換性のためにのみ存在します。Java 7u51から、ACC_SUPERは、セキュリティ上の理由で完全に無視されることに注意してください。

  • jsr / ret バイトコードです。

    これらのバイトコードは、サブルーチンの実装(主に finally ブロック)。それらは Java 6以降、生成されなくなった . 非推奨の理由は、静的検証を非常に複雑にしてしまい、大きな効果が得られないからです(つまり、使用するコードはほとんど通常のジャンプで再実装でき、オーバーヘッドもほとんどありません)。

  • 戻り値の型が異なるだけの2つのメソッドをクラス内に持つこと。

    Java言語仕様では、同じクラスにある2つのメソッドが のみです。 は、その戻り値の型(すなわち、同じ名前、同じ引数リスト、...)です。しかし、JVMの仕様には、そのような制限がないので、クラス・ファイル できる このようなメソッドが2つ含まれていても、通常のJavaコンパイラでそのようなクラスファイルを作成する方法はありません。このようなクラスファイルは、通常のJavaコンパイラでは作成できません。 この回答 .