21

私はJavaの問題のわずかなバリエーションに遭遇し続けています.

final であるが動的なオブジェクト プロパティがあります。つまり、一度割り当てられた値を定数にしたいのですが、値はランタイムごとに異なる場合があります。そのため、クラスの先頭でクラス レベル変数を宣言しますprivate final FILE_NAME;。次に、コンストラクターで値を割り当てます-たとえばFILE_NAME = buildFileName();

buildFileName()メソッドに例外をスローするコードがあると、問題が発生します。だから私はコンストラクタで次のようなことを試みます:

try{
   FILE_NAME = buildFileName();
}
catch(Exception e){
   ...
   System.exit(1);
}

「空白の最終フィールド FILE_NAME が初期化されていない可能性があります」というエラーが表示されます。ここで、Java の厳密なコンパイラーに少しイライラし始めます。キャッチに到達するとプログラムが終了するため、これが問題にならないことはわかっています...しかし、コンパイラはそれを認識しないため、このコードを許可しません。キャッチにダミーの割り当てを追加しようとすると、「最後のフィールド FILE_NAME は既に割り当てられている可能性があります」というメッセージが表示されます。一度しか割り当てられないため、try-catch の前にデフォルト値を割り当てることは明らかにできません。

何か案は...?

4

5 に答える 5

20

どうですか

String tempName = null;
try{
   tempName = buildFileName();
}
catch(Exception e){
   ...
   System.exit(1);
}
FILE_NAME = tempName;
于 2010-05-05T13:55:38.087 に答える
7

また

try {
   FILE_NAME = buildFileName();
} catch (Exception e){
   ...
   System.exit(1);
   throw new Error();
}

または一部の人が好む:

private static final String FILE_NAME = fileName();

private static String fileName() {
    try {
        return buildFileName();
    } catch (Exception e){
        ...
        System.exit(1);
        throw new Error();
    }
}

しかしSystem.exit、静的イニシャライザーを呼び出すことはおそらく悪い考えです。それはあなたのユニットテストを台無しにするでしょう。

于 2010-05-05T14:07:19.143 に答える
4

考え直して、解決策を思いついたと思います!- 中間変数を使用します。

String fileName = null;
try{
   fileName = buildFileName();
}
catch(Exception e){
   ...
   System.exit(1);
}
FILE_NAME = fileName;

なぜこれを考えるのにそんなに時間がかかったのかわからない...

于 2010-05-05T13:55:15.983 に答える
1

個人的にはエラーをスローします。エラーフローが適切に設計されている場合、 System.exit() は冗長になるはずです。エラーがスローされた場合、プログラムはおそらく荒野に突入しません...?

于 2010-05-05T14:16:25.230 に答える
0

OPの問題と同じように、ファイルシステムの.propertiesファイルから読み込まれる最終フィールドに値を割り当てる方法を見つける必要があったため、それまでアプリは値を認識できませんでした起こりました。アプリの起動時に .properties ファイルの内容を Properties オブジェクトに読み取った後、一般化されたメソッド呼び出しを使用して値を割り当てるという Hail Mary パスは、ありがたいことにうまくいきました。また、番号を制限します。Properties オブジェクトが現在 null であるかどうかを確認するためのコード チェックによって、アプリがメモリに読み込まれるたびにファイルを 1 回読み取る必要があります。しかし、一度割り当てられると、フィールドを操作して「最終」ステータスを変更する以外は、最終フィールドの値を変更することはできません。https://stackoverflow.com/a/3301720/1216686 - 卑劣ですが、大好きです!)。NPE などの一般的な実行時エラー チェックを簡潔にするために省略したコード例:

import java.util.Properties;

public class MyConstants {

  private static Properties props; // declared, not initialized,
                                   // so it can still be set to
                                   // an object reference.

  public static String MY_STRING = getProperty("prop1name", "defaultval1");
  public static int MY_INT = Integer.parseInt(getProperty("prop2name", "1"));
  // more fields...

  private static String getProperty(String name, String dflt) {
   if ( props == null ) {
     readProperties();
   }
   return props.getProperty(name, dflt);
  } 

  private static void readProperties() {
     props = new Properties(); // Use your fave way to read
                      // props from the file system; a permutation
                      // of Properties.load(...) worked for me.
  } 

  // Testing...
  public static void main(String[] args) {
      System.out.println(MY_STRING);
      System.out.println(MY_INT);
  }

}

これにより、プロパティを外部化してアプリに読み込むことができ、値を保持するために使用されるフィールドを「最終」としてマークすることができます。また、Properties クラスの getProperty() により、メソッドの呼び出しコードがデフォルト値を渡して、プロパティのキーと値のペアが外部で見つからなかった場合に使用できるため、最終的なフィールド値の戻り値を保証することもできます。 .properties ファイル。

于 2014-10-28T22:13:39.920 に答える