この記事では主に、クラスファイルの分析を通じてJavaクラスパーサーの実装方法の例を紹介します。これは一定の参考価値があり、必要な友人がそれについて学ぶことができます。
私は現在、ClassAnalyzer というプライベート プロジェクトを書いています。ClassAnalyzer の目的は、Java クラス ファイルの設計と構造を深く理解することです。主要な枠組みと基本的な機能は完成していますが、今後、いくつかの詳細な機能が追加される予定です。実際、JDK は Class ファイルを逆コンパイルするためのコマンド ライン ツール javap をすでに提供していますが、この記事ではパーサーの実装に関する私の考えを明確にします。
クラス ファイル
クラスまたはインターフェイス情報のキャリアとして、各クラス ファイルはクラスを完全に定義します。 Java プログラムを「一度書けばどこでも実行できる」ようにするために、Java 仮想マシンの仕様では Class ファイルに厳しい規制が設けられています。 Class ファイルを構成する基本的なデータ単位はバイトです。このため、クラス ファイル全体に格納される内容は、1 バイトでは表現できないデータとなります。複数 連続したバイトで表されます。
Java 仮想マシンの仕様によれば、クラス ファイルは C 言語の構造に似た擬似構造を使用してデータを保存します。この擬似構造には符号なし数値とテーブルの 2 つのデータ型のみがあります。 Java 仮想マシンの仕様では、u1、u2、u4、および u8 がそれぞれ 1 バイト、2 バイト、4 バイト、および 8 バイトの符号なし数値を表すように定義されています。符号なし数値は、参照、数量、または文字列を記述するために使用できます。テーブルは、データ項目として複数の符号なし数値または他のテーブルで構成される複合データ型であり、階層複合構造でデータを記述するために使用されるため、クラス ファイル全体が本質的にテーブルになります。 ClassAnalyzer では、byte、short、int、long がそれぞれ u1、u2、u4、u8 のデータ型に対応します。Class ファイルは次の Java クラスとして記述されます。
public class ClassFile { public U4 magic; // magic public U2 minorVersion; // minor_version public U2 majorVersion; // major_version public U2 constantPoolCount; // constant_pool_count public ConstantPoolInfo[] cpInfo; // cp_info public U2 accessFlags; // access_flags public U2 thisClass; // this_class public U2 superClass; // super_class public U2 interfacesCount; // interfaces_count public U2[] interfaces; // interfaces public U2 fieldsCount; // fields_count public FieldInfo[] fields; // fields public U2 methodsCount; // methods_count public MethodInfo[] methods; // methods public U2 attributesCount; // attributes_count public BasicAttributeInfo[] attributes; // attributes }
クラスファイルを構成する各データ項目(マジックナンバー、クラスファイルのバージョン、その他のデータ項目、アクセスフラグ、クラスインデックス、親クラスインデックスなど)の解析方法
は各クラス ファイル内にあり、それぞれが固定バイト数を占有し、解析中に対応するバイト数のみを読み取る必要があります。また、柔軟に対応する必要がある部分は主に、定数プール、フィールドテーブルコレクション、メソッドテーブルコレクション、属性テーブルコレクションの4つです。フィールドとメソッドは独自の属性を持つことができ、クラス自体にも対応する属性があるため、フィールド テーブル コレクションとメソッド テーブル コレクションの解析には属性テーブルの解析も含まれます。
定数プールはクラス ファイル内のデータの大部分を占め、数値定数、文字列定数、クラス名、インターフェイス名、フィールド名、メソッド名などを含むすべての定数情報を保存するために使用されます。 Java 仮想マシンの仕様では複数の定数タイプが定義されており、それぞれが独自の構造を持っています。定数プール自体はテーブルであり、解析する際に注意すべき点がいくつかあります。
各定数型は、u1 型タグによって識別されます。
ヘッダーに指定された定数プール サイズ (constantPoolCount) は、実際の値より 1 大きくなります。たとえば、constantPoolCount が 47 に等しい場合、定数プールには 46 個の定数があります。
定数プールのインデックス範囲は 1 から始まります。たとえば、constantPoolCount が 47 の場合、定数プールのインデックス範囲は 1 ~ 46 です。項目 0 を空のままにする設計者の目的は、「定数プール項目を参照しない」ことを表現することです。
CONSTANT_Utf8_info 定数の構造には、タイプ u1 のタグ、タイプ u2 の length バイト、およびタイプ u1 の length バイトの連続データが MUTF-8 (Modified UTF-8) 文字列を使用してエンコードされます。 MUTF-8 は UTF-8 と互換性がありません。主な違いは 2 つあります。1 つ目は、NULL 文字が 2 バイト (0xC0 および 0x80) にエンコードされることです。2 つ目は、補助文字がサロゲート ペアに分割され、UTF に従って個別にエンコードされることです。 -16 、関連する詳細はここにあります (バリアント UTF-8)。
属性テーブルは、特定のシナリオに固有の情報を記述するために使用されます。クラス ファイル、フィールド テーブル、メソッド テーブルにはすべて、対応する属性テーブル セットがあります。 Java 仮想マシン仕様ではさまざまな属性が定義されており、現在 ClassAnalyzer は一般的に使用される属性の分析を実装しています。定数タイプのデータ項目とは異なり、属性には属性のタイプを識別するためのタグがありませんが、各属性にはタイプ u2 のattribute_name_indexが含まれており、Attribute_name_indexは、属性の名前を含む定数プール内のタイプCONSTANT_Utf8_infoの定数を指します。属性を解析するとき、ClassAnalyzer は、attribute_name_index が指す定数に対応する属性名を通じて属性のタイプを認識します。
フィールド テーブルは、クラスまたはインターフェイスで宣言された変数を記述するために使用されます。フィールドには、クラス レベルの変数とインスタンス レベルの変数が含まれます。フィールドテーブルの構造は、u2タイプaccess_flags、u2タイプname_index、u2タイプdescriptor_index、u2タイプattributes_count、attributes_countattributes_infoタイプの属性を含む。属性テーブルの解析についてはすでに紹介しましたが、属性の解析方法は属性テーブルの解析方法と一致しています。
Class的文件方法表采用了和字段表相同的存储格式,只是access_flags对应的含义有所不同。方法表包含着一个重要的属性:Code属性。Code属性存储了Java代码编译成的字节码指令,在ClassAnalyzer中,Code对应的Java类如下所示(仅列出了类属性)
public class Code extends BasicAttributeInfo { private short maxStack; private short maxLocals; private long codeLength; private byte[] code; private short exceptionTableLength; private ExceptionInfo[] exceptionTable; private short attributesCount; private BasicAttributeInfo[] attributes; ... private class ExceptionInfo { public short startPc; public short endPc; public short handlerPc; public short catchType; ... } }
在Code属性中,codeLength和code分别用于存储字节码长度和字节码指令,每条指令即一个字节(u1类型)。在虚拟机执行时,通过读取code中的一个个字节码,并将字节码翻译成相应的指令。另外,虽然codeLength是一个u4类型的值,但是实际上一个方法不允许超过65535条字节码指令。
代码实现
ClassAnalyzer的源码已放在了GitHub上。在ClassAnalyzer的README中,我以一个类的Class文件为例,对该Class文件的每个字节进行了分析,希望对大家的理解有所帮助。
以上がJavaでクラスパーサを実装する方法の例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

javaispopularforsoss-platformdesktopapplicationsduetoits "writeonce、runaynay" philosophy.1)itusesbytecodatiTatrunnanyjvm-adipplatform.2)ライブラリリケンディンガンドジャヴァフククレアティック - ルルクリス

Javaでプラットフォーム固有のコードを作成する理由には、特定のオペレーティングシステム機能へのアクセス、特定のハードウェアとの対話、パフォーマンスの最適化が含まれます。 1)JNAまたはJNIを使用して、Windowsレジストリにアクセスします。 2)JNIを介してLinux固有のハードウェアドライバーと対話します。 3)金属を使用して、JNIを介してMacOSのゲームパフォーマンスを最適化します。それにもかかわらず、プラットフォーム固有のコードを書くことは、コードの移植性に影響を与え、複雑さを高め、パフォーマンスのオーバーヘッドとセキュリティのリスクをもたらす可能性があります。

Javaは、クラウドネイティブアプリケーション、マルチプラットフォームの展開、および言語間の相互運用性を通じて、プラットフォームの独立性をさらに強化します。 1)クラウドネイティブアプリケーションは、GraalvmとQuarkusを使用してスタートアップ速度を向上させます。 2)Javaは、埋め込みデバイス、モバイルデバイス、量子コンピューターに拡張されます。 3)Graalvmを通じて、JavaはPythonやJavaScriptなどの言語とシームレスに統合して、言語間の相互運用性を高めます。

Javaの強力なタイプ化されたシステムは、タイプの安全性、統一タイプの変換、多型を通じてプラットフォームの独立性を保証します。 1)タイプの安全性は、コンパイル時間でタイプチェックを実行して、ランタイムエラーを回避します。 2)統一された型変換ルールは、すべてのプラットフォームで一貫しています。 3)多型とインターフェイスメカニズムにより、コードはさまざまなプラットフォームで一貫して動作します。

JNIはJavaのプラットフォームの独立を破壊します。 1)JNIは特定のプラットフォームにローカルライブラリを必要とします。2)ローカルコードをターゲットプラットフォームにコンパイルおよびリンクする必要があります。3)異なるバージョンのオペレーティングシステムまたはJVMは、異なるローカルライブラリバージョンを必要とする場合があります。

新しいテクノロジーは、両方の脅威をもたらし、Javaのプラットフォームの独立性を高めます。 1)Dockerなどのクラウドコンピューティングとコンテナ化テクノロジーは、Javaのプラットフォームの独立性を強化しますが、さまざまなクラウド環境に適応するために最適化する必要があります。 2)WebAssemblyは、Graalvmを介してJavaコードをコンパイルし、プラットフォームの独立性を拡張しますが、パフォーマンスのために他の言語と競合する必要があります。

JVMの実装が異なると、プラットフォームの独立性が得られますが、パフォーマンスはわずかに異なります。 1。OracleHotspotとOpenJDKJVMは、プラットフォームの独立性で同様に機能しますが、OpenJDKは追加の構成が必要になる場合があります。 2。IBMJ9JVMは、特定のオペレーティングシステムで最適化を実行します。 3. Graalvmは複数の言語をサポートし、追加の構成が必要です。 4。AzulzingJVMには、特定のプラットフォーム調整が必要です。

プラットフォームの独立性により、開発コストが削減され、複数のオペレーティングシステムで同じコードセットを実行することで開発時間を短縮します。具体的には、次のように表示されます。1。開発時間を短縮すると、1セットのコードのみが必要です。 2。メンテナンスコストを削減し、テストプロセスを統合します。 3.展開プロセスを簡素化するための迅速な反復とチームコラボレーション。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

WebStorm Mac版
便利なJavaScript開発ツール

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

メモ帳++7.3.1
使いやすく無料のコードエディター

ホットトピック









