0Pricing
Java Academy · レッスン

javapでバイトコードを調べる

javap -cでクラスファイルを逆コンパイルし、Javaの構文がバイトコードにどう変換されるかを理解します。

「javapでバイトコードを調べる」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

バイトコードを調べる理由

バイトコードを理解すると、JVM が Java コードを実際にどのように実行するかが分かります。パフォーマンス問題のデバッグ、コンパイラーの最適化の理解、合成コード(ラムダや内部クラス)が想定どおりに動作することの確認に役立ちます。

javapの基本的な使い方

javap ClassName は、クラスの公開 API(メソッドシグネチャ、フィールド宣言)を表示します。現在のディレクトリまたはクラスパスから .class ファイルを読み込みます。

# Compile first:
javac User.java
# Display public API:
javap User
# Output:
# public class User {
#   public java.lang.String getName();
#   public int getAge();
# }

-cでバイトコードを逆アセンブル

javap -c User は、各メソッドの JVM 命令セット(オペコード)を表示します。実行フローを理解するための中心的なビューです。

# javap -c User
# public java.lang.String getName();
#   Code:
#      0: aload_0
#      1: getfield      #2  // Field name:Ljava/lang/String;
#      4: areturn

-vによる詳細出力

javap -v User は、定数プール、アクセスフラグ、スタックサイズ、例外テーブルを追加で表示します。詳細な分析や ClassCastException のデバッグに不可欠です。

# javap -v User
# Constant pool:
#    #1 = Methodref  #5.#22  // java/lang/Object."<init>":()V
#    #2 = Fieldref   #4.#23  // User.name:Ljava/lang/String;
# ...

よく使われるバイトコード命令

頻出するオペコードを把握しておきましょう: aload_0(this のロード)、getfield、putfield、invokevirtual、invokespecial(コンストラクター/private)、invokestatic、invokedynamic(ラムダ)、return、areturn。

ラムダとinvokedynamic

ラムダ式は invokedynamic 命令にコンパイルされます。最初の呼び出しでは LambdaMetafactory を使用してクラスを生成し、以降の呼び出しではそれを再利用します。javap -v でブートストラップメソッドのテーブルを確認できます。

// Java:
list.forEach(s -> System.out.println(s));
// Compiles to invokedynamic — javap shows:
// invokedynamic #4,0  // InvokeDynamic #0:accept:()Ljava/util/function/Consumer;

文字列連結の最適化

最新の javac は、"Hello " + name に対して StringBuilder ではなく invokedynamic を使用します。javap -v で StringConcatFactory のブートストラップメソッドを確認できます。

// Java 9+ string concat:
String s = "Hello " + name;
// Compiles to:
// invokedynamic #5,0  // InvokeDynamic #1:makeConcatWithConstants

内部クラスへのアクセスを確認する

外部クラスが内部クラスの private フィールドにアクセスする場合(またはその逆の場合)、コンパイラーは合成された access$000 メソッドを生成します。javap -p(private メンバー)で確認できます。

# javap -p OuterClass
# static int access$000(OuterClass);
# -- synthetic bridge method generated by the compiler

オートボクシングのコストを確認する

オートボクシングは、Integer.valueOf() または int.intValue() の呼び出しにコンパイルされます。javap -c を使用してボクシングが発生していることを確認し、プリミティブ型を使うべきか判断してください。

// Java:
List<Integer> list = new ArrayList<>();
list.add(42); // autoboxing
// Bytecode:
// bipush 42
// invokestatic java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

バイトコードからtry-catchを読み取る

例外ハンドラーは例外テーブルのエントリとして現れ、javap -v で確認できます。各エントリには try の開始位置、終了位置、ハンドラー、捕捉する型が示されます。

# Exception table:
# from    to  target  type
#    2    10      15  Class java/io/IOException
# -- means: if IOException in bytes 2-10, jump to handler at byte 15

クラスファイルヘッダー

クラスファイルヘッダーには、マジックナンバー(CAFEBABE)、メジャー/マイナーバージョン、アクセスフラグが含まれます。javap -v でメジャーバージョンを確認できます。この値から、そのクラスをコンパイルした Java リリースが分かります。

# javap -v User
# minor version: 0
# major version: 61   <- Java 17
# flags: ACC_PUBLIC, ACC_SUPER

確認問題

各メソッドの JVM オペコードを表示する javap のフラグはどれですか?

まとめ

オペコードには javap -c を、詳細情報全体には javap -v を使用します。主要なオペコードとして、invokevirtual、invokespecial、invokedynamic、getfield を把握しておきましょう。ラムダ、ボクシング、文字列連結を調べると、コンパイラーの出力を理解できます。

よくある質問

「javapでバイトコードを調べる」レッスンは無料ですか?

はい。「javapでバイトコードを調べる」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「javapでバイトコードを調べる」で何を学びますか?

javap -cでクラスファイルを逆コンパイルし、Javaの構文がバイトコードにどう変換されるかを理解します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「javapでバイトコードを調べる」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. クラスロードの段階:ロード、リンク、初期化
  2. ClassLoader の階層とカスタムローダー
  3. javapでバイトコードを調べる
  4. JITコンパイルと階層型コンパイル
← Java Academyに戻る