GolangはじめにJavaのプログラムがどうやって動いているのかを知りたい。手始めに、javaのクラスファイルの中身がどうなっているか、特にプログラム中の各種名前(クラス/関数/フィールドなど)や固定値をどうやって格納しどうやってそれを参照しているかについて調べる。Javaバイトコードとして定義された命令セットを実行するスタック型の仮想マシン。してリリースされている。この環境を移植することで、さまざまな環境でJavaのプログラムを実行することができる。上で実行可能なJavaバイトコードを含む(.class拡張子付きの)ファイルである。(wikipediaより)JavaバイトコードとはJavaバイトコードは、Java仮想マシンが実行する命令形式である。各バイトコードのオペコードは長さが1バイトであるが、引数を持つものもあるため、結果として複数バイトの命令となる。種類を指定する部分のこと、およびそのコード(符号)のことである。数式における演算子に相当する。命令のもうひとつの主要部分は、操作される対象を指定するオペランド(被演算子)である。(wikipediaより)Java仮想マシンは、Javaクラスファイルの中身(Javaバイトコード)を解釈して動作する。Javaバイトコードは、Java仮想マシンの命令である。命令はオペコードと呼ばれる。オペコードの操作対象はオペランドと呼ばれる。手っ取り早く体験するために、Javaで「Helloworld」を書いてコンパイルしてHelloWorld.classを作成し、それをダンプして中身を見てみる。...........xxdコマンドを使って16進数で表示する。文字列出力で来そうな箇所は文字列出力する。(例:Ljava/lang/String;)"["は見つかるが、"]"は無い。コマンド)を準備している。1つ以上のクラス・ファイルを逆アセンブルします。ディスアセンブラ)は、逆コンパイラの一種であるが、実行ファイルないしオブジェクトファイルの機械語コード(とシンボルテーブルなどの付随情報)を基に、アセンブリ言語ソースコードを生成する、すなわちアセンブラの逆の作用をするものを特に指す。コンピュータが直接実行できるプログラムは数字の羅列である機械語であり、人間が直接理解することは困難である。この機械語は、人間にわかりやすいソースコードを、アセンブラやコンパイラ、リンカといったソフトウェアによって機械的に変換して得られたものに過ぎないので、プログラマはソースコードを理解してソフトウェアを開発すればよい。機械語に変換されており、元のソースコードも手に入らない場合は、アセンブリとは逆の手順をたどる(逆アセンブリする)ことで擬似的にソースコードを復元することができる。(wikipediaより)JavaバイトコードはJava仮想マシンの機械語である。Java仮想マシンの逆アセンブルコマンド(逆アセンブラ)であるjavapコマンドで人間にわかりやすいソースコードを生成する。return}■気になる点ソースコードには無いキーワードがある。クラスファイルの構造Javaクラスファイルのフォーマットはざっくり説明すると以下の通り。属性テーブルJavaクラスファイルのフォーマット仕様に従って中身を見るjavapコマンドでJavaクラスファイルの中身を見ることができたが、ここではJavaクラスファイルのフォーマット仕様に従って頭から1バイトづつ取り出して中身を確認する。Javaクラスファイルのフォーマット仕様に従ってファイルの内容を表示するプログラムをgo言語で実装する。いうような情報のテーブルである。(wikipediaより)一般的なコンパイラがコンパイルして出力するオブジェクトファイル(今回の場合はJavaクラスファイル)はおおよそ以下のような構造になっている。ConstantPoolテーブルエントリ数は2バイト。(エントリ数の最大65,535)。nameAndTypeIndex:15とある。1番目のエントリは6番目のエントリと15番目のエントリを参照していることを表す。nameIndex:22とある。6番目のエントリは22番目のエントリを参照していることを表す。content:java/lang/Objectとある。ConstantPoolの参照を解決すると以下の通り。後半のThisClassIndexSuperClassIndexmethod#0method#1に注目する。6はConstantClassjava/lang/Objectであることがわかる。method命令セット仕様を読むとわかるが、method#0、method#1に含まれるオペコードのうち、オペランドを持つものはinvokespecialgetstaticldcinvokevirtualである。indexbyte1およびindexbyte2は、インデックスの値が(indexバイト1<<8)|indexbyte2である現在のクラス(§2.6)の実行時定数プールにインデックスを構築するために使用されます。.3節)、およびメソッドが検索されるクラスまたはインタフェースへのシンボリック参照を与えます。指定されたメソッドが解決されます(§5.4.3.3、§5.4.3.4)。(「みらい翻訳」で翻訳)とある。1の結果)のメソッド名(とそのクラス名)を指しているっぽい。java/lang/Object."<init>":()Vのコメントの内容と一致している。ConstantPool#2であるConstantFieldRefConstantClassnamejava/lang/SystemConstantNameAndTypenameoutdescriptorLjava/io/PrintStream;を指す。java/lang/System.out:Ljava/io/PrintStream;のコメントの内容と一致している。World!!のコメントの内容と一致している。(仕様を読むとわかるがldcのオペランドは1バイト。ldc_wというのもありそのオペランドは2バイト。java/io/PrintStream.println:(Ljava/lang/String;)Vのコメントの内容と一致している。まとめJavaクラスファイルの中にはクラス名、関数名、フィールド名を構造的に格納するシンボルテーブルがある。Javaクラスファイルの中にはJava仮想マシンの命令があり、シンボルテーブルのエントリを参照している。おまけJavaプログラマは、Javaバイトコードについて全く知ったり理解する必要はない。IBMのdeveloperWorksによると、「バイトコードを理解することと、どんなバイトコードがJavaコンパイラにより生成される可能性が高いを理解することは、アセンブリ言語の知識がCやC++プログラマの助けになるのと同じように、Javaプログラマの助けになる」とされている。サーバーレス化する月別アーカイブはてなブログをはじめよう!linkodeさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。