11

Java が次のシナリオをどのように処理するかを知りたいです。

次のような Debug というクラスがあるとします。

public class Debug 
{
    private static final boolean isAssertEnabled = true;

    public static void assertTrue(boolean b, String errorMessage) {
        if (isAssertEnabled) {
            if (!b) {
                throw new RuntimeException(errorMessage);
            }
        }
    }
}

私のコードに次のような呼び出しがあるとします。

...
Debug.assertTrue((x + y != z) && (v - u > w), "Some error message");
....

いくつかの質問を聞きたいんです:

  1. isAssertEnabledフラグがfalseに設定されている場合、 Debug.assertTrueへの呼び出し全体がコンパイルされますか? isAssertEnabled == true かどうかのチェックは、関数が呼び出された後に関数内でのみ行われることに注意してください。
  2. 呼び出し全体がコンパイルされた場合、それはブール式の評価もコンパイルされたことを意味しますか? その式をただで評価するのはもったいないでしょう。

助けてくれてありがとう!

4

3 に答える 3

6

ブール式の評価は、少なくとも javac によってコンパイルされるべきではありません。

Debugクラスファイルが現在値に対して何もしていない場合でも、実行時にそれが当てはまると誰が言えるでしょうか?

Debug クラスをコンパイルした後 (isAssertEnabled静的にすることによって)、javac にはまだコードが含まれていますが、JIT コンパイラがそれを削除することを期待しています (ただし、Peter が参照した質問が表示されるはずです)。メソッドを何もインライン化できないかどうかはわかりません。繰り返しになりますが、JIT コンパイラーがそれを実行でき、引数の評価に副作用がないことがわかった場合、評価を回避できる可能性があります。ただし、それに応じて個人的にコードを書くことはありません。

于 2011-01-21T07:47:49.087 に答える
3

Javaがすでにネイティブに提供しているものを構築しようとしているのはなぜですか?

assertキーワードはあなたが望むことを正確に実行します:その実行は(パッケージごとのレベルで)オンとオフを切り替えることができ、アサーションが無効になっている場合はブール式の評価が回避されます。

于 2011-01-21T08:21:59.933 に答える
2

これは、Log4jの「isTraceEnabled()」、「isDebugEnabled()」などを思い出させます。不必要なログステートメントの評価を避けるために、ifステートメントでログステートメントを明示的にwrpaする必要があります。

if(logger.isDebugEnabled() {
        logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}

ここの「パフォーマンス」を参照してください

于 2011-01-21T07:58:57.487 に答える