IntelliJのデバッグトリック

1概要

このチュートリアルでは、いくつかの高度なIntelliJデバッグ機能について説明します。

デバッグの基本(デバッグの開始方法、[ステップイン]、[ステップオーバー]など)は既にわかっていると想定しています。そうでない場合は、その詳細についてはhttps://www.baeldung.com/intellij-basics[この記事]を参照してください。

2スマートステップイン

doJob(getArg1()、getArg2()) のように、1行のソースコードで複数のメソッドが呼び出される場合があります。 Step Into action(F7)を呼び出すと、デバッガーは評価のためにJVMによって使用される順序でメソッドにアクセスします。 getArg1 - getArg2 - doJob

ただし、** すべての中間呼び出しをスキップして直接ターゲットメソッドに進むことができます。[スマートステップイン]アクションでこれを実行できます。

これはデフォルトで** Shift + F7にバインドされており、呼び出されると次のようになります。

これで、先に進む方法を選択できます。また、IntelliJは常に最も外側のメソッドをリストの一番上に配置します。それは私達が Shift F7 |を押すことによってそれにすぐに行くことができることを意味します。 入る

3ドロップフレーム

私たちが興味を持っている何らかの処理(例えば、現在のメソッド引数の計算)がすでに起こっていることに気づくかもしれません。この場合、それらを再処理するために現在のJVMスタックフレームをドロップすることが可能です。

以下の状況を検討してください。

getArg1 処理のデバッグに興味があるとします。そのため、現在のフレームをドロップします( doJob メソッド)。

私たちは前の方法にいます :

しかし、呼び出し引数はすでにこの時点で計算されているので、 現在のフレームも削除する必要があります :

  • これで、 Step Into を呼び出して処理を再実行できます。

4フィールドブレークポイント

非プライベートフィールドは、セッターを介さずに直接他のクラスによって変更されることがあります(これは、ソースコードを制御できないサードパーティのライブラリの場合です)。

そのような状況では、いつ修正が行われるのか理解するのが難しいかもしれません。 IntelliJでは、それを追跡するためにフィールドレベルのブレークポイントを作成することができます。

それらはいつものように設定されています - フィールドライン上の左側のエディタ溝を左クリックしてください。その後、 ブレークポイントのプロパティを開き(ブレークポイントマークを右クリックして)、フィールドの読み取り、書き込み、またはその両方に関心があるかどうかを設定することができます

5ログブレークポイント

アプリケーションに競合状態があることを知っていることがありますが、それが正確にどこにあるのかわからない場合があります。特に新しいコードで作業している間は、それを突き止めるのは難しいかもしれません。

プログラムのソースにデバッグ文を追加できます。ただし、サードパーティのライブラリにはそのような機能はありません。

IDEはここで役に立ちます - 一度ヒットすると実行をブロックしないブレークポイントを設定できますが、代わりにロギングステートメントを生成します

次の例を見てください。

public static void main(String[]args) {
    ThreadLocalRandom random = ThreadLocalRandom.current();
    int count = 0;
    for (int i = 0; i < 5; i++) {
        if (isInterested(random.nextInt(10))) {
            count++;
        }
    }
    System.out.printf("Found %d interested values%n", count);
}

private static boolean isInterested(int i) {
    return i % 2 == 0;
}

実際の isInterested 呼び出しのパラメータをログに記録することに興味があるとします。

ターゲットメソッドにノンブロッキングブレークポイントを作成しましょう(左のエディタ溝を Shift -左クリック)。その後、そのプロパティを開き(ブレークポイントを右クリック)、 logするターゲット式を定義しましょう :

アプリケーションを実行すると(デバッグモードを使用する必要があります)、出力が表示されます。

isInterested(1)
isInterested(4)
isInterested(3)
isInterested(1)
isInterested(6)
Found 2 interested values

6. 条件付きブレークポイント

特定のメソッドが複数のスレッドから同時に呼び出される状況があり、特定の引数に対して処理をデバッグする必要があります。

IntelliJでは、ユーザー定義の条件が満たされた場合にのみ実行を一時停止するブレークポイントを作成することができます。

上記のソースコードを使用した例を次に示します。

与えられた引数が3より大きい場合にのみ、デバッガはブレークポイントで停止します。

7. オブジェクトマーク

これは最も強力で知られていないIntelliJの機能です。それは本質的に非常に単純です - カスタムラベルをJVMオブジェクトに添付することができます

それを実証するために使用するアプリケーションを見てみましょう。

public class Test {

    public static void main(String[]args) {
        Collection<Task> tasks = Arrays.asList(new Task(), new Task());
        tasks.forEach(task -> new Thread(task).start());
    }

    private static void mayBeAdd(Collection<Integer> holder) {
        int i = ThreadLocalRandom.current().nextInt(10);
        if (i % 3 == 0) {
            holder.add(i);
        }
    }

    private static class Task implements Runnable {

        private final Collection<Integer> holder = new ArrayList<>();

        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                mayBeAdd(holder);
            }
        }
    }
}

7.1. マークを作成する

アプリケーションがブレークポイントで停止し、ターゲットがスタックフレームから到達可能なときに、オブジェクトにマークを付けることができます。

それを選択し、 F11 Mark Object action)を押してターゲット名を定義します。

7.2. マークを見る

これで、アプリケーションの他の部分でもカスタムオブジェクトラベルを確認できます。

クールなことは、** マークされたオブジェクトが現在スタックフレームから到達できなくても、その状態を見ることができるということです。

IntelliJはそれを __DebugLabel 接尾辞で完成させることを申し出ます:

評価すると、ターゲットオブジェクトの状態が表示されます。

** 7.3. 条件としてマーク

ブレークポイント条件でマークを使用することも可能です。

8結論

マルチスレッドアプリケーションのデバッグ中に、生産性を大幅に向上させるいくつかの手法を確認しました。

これは通常やりがいのある作業ですが、ここではツールによる支援の重要性を軽視することはできません。