3

以下は私のコードのスニペットです:

class A { 

   private boolean debug = false;

   // Called when server boots up.
   public void init (property) { 
      debug = property.getBoolean ("debug_var"); // read debug from a config file.
   }

   // some other function  
   public void foo () { 
       if (debug) { 
                 System.out.println ("From inside the debug block");
       }
   }
 }

コードを実行すると、if (debug) が実際に「From inside debug block」を出力する if debug == true が構成ファイルに表示されます。

2 つの質問:

  1. では、この場合、変数 debug の値が実行時に変更される可能性があるという理由だけで、コンパイラは if ブロックを .class ファイルに含めますか?

  2. これが正しい場合、特定の環境で一部のコードが .class ファイルに追加されないようにするにはどうすればよいですか?

4

6 に答える 6

5

このようなことをしなければならない場合、ほとんどのロギング フレームワークには、ログの詳細レベルを設定する独自の手段があり、実行時に低レベルすぎるログ ステートメントを出力しません。これを適切に行うには、ロギング フレームワークを使用します。

たとえば、組み込みの java.util.logging フレームワークを使用すると、次のようになります。

Logger.getLogger("ThisClass").log(Level.FINE, "Log message");

これは、ログ レベルが FINE 以下に設定されている場合にのみ出力されますが、ログ レベルが CONFIG 以下の場合は無視されます。

「条件付きコンパイル」は、Java では一般的に意味のあることではありませんが、注意を払って、JIT は決して実行されないと判断できるブランチを最適化して取り除きます。

于 2012-06-11T19:06:12.827 に答える
1

他の人が指摘しているように、Java コンパイラは通常、非常に素朴で、Java ソース コードとして持っているものを Java バイトコードに変換するだけです。たとえば、ifステートメントは、分岐条件が常に false であることが明らかであるかどうかに関係なく、ほとんどの場合、条件付き分岐に変換されます。

ただし、理論的な観点からは、コンパイラが特定の分岐を取得できないことを理解し、バイトコードでそれらを単に省略することを妨げるものは何もありません。Java 言語仕様には、バイトコードを対象とする場合のコンパイル方法は規定されていません。

于 2012-06-11T19:11:07.143 に答える
1

最も近い方法は、実行時に (本質的に) 役に立たない静的変数を使用することです。

ただし、あなたの例では、JVMは十分な回数実行された後に最適化する可能性が高いため、懸念が実行時の効率である場合、心配する価値はないでしょう。

最終的に、環境に基づいてクラスファイルからコードを削除する理由をお尋ねします。それが実行時に変更できるものではない場合、最善の選択肢は、決定/注入できる何らかの形のプラグ可能な実装を作成することです。実行時に。

于 2012-06-11T19:11:25.360 に答える
0

以前は、ブール値をstaticandとして宣言し、finalその値を に設定するfalseと、コンパイラがコードを省略していました。ただし、それは元の Java コンパイラでした。ただし、現在のものがこれを行うかどうかはわかりません(現在のものは長い間存在しています)。この背後にある理論的根拠は、アプレットのダウンロードを小さくできるようにすることでした。これはせいぜい不格好なメカニズムであったため、広く使用されていませんでした。

これをテストするには、デバッグ変数を変更してprivate static final boolean debug=false;コンパイルし、クラス ファイルを保存してから true に切り替えます。次に、再度コンパイルして、クラス ファイルが異なるかどうかを確認します。ところで、debug が final として宣言されている場合、init 関数は機能しません。

于 2012-06-11T19:09:43.393 に答える
0

条件付きコンパイルのようなものはありません (Java が実行されないことが保証されている条件を見つけない限り)。クラス ファイルには、Java ファイルにあるものと同等のバイト コードが含まれています。

編集:aiobeeが指摘したように、コンパイラは、分岐ステートメントが実行されないと判断した場合、分岐ステートメントを省略する場合があります。

于 2012-06-11T19:06:02.373 に答える
0
  1. はい、コンパイラはこれを .class ファイルに含めます。
  2. 条件付きコンパイルのメカニズムはありません。コンパイラ プラグイン (JDK 1.7 以降) を使用してその一部をエミュレートするか、AspectJ などのバイトコード操作技術を使用して同様の効果を達成することを試みることができます。
于 2012-06-11T19:07:50.320 に答える