次のファイルを読みたいとします。
TestFile;100
クラスのフィールドに:
public class MyReader {
String field1;
Integer field2;
}
コンテンツを読むには、わずかに異なる 2 つの方法があります。
パブリック クラス MyReader {
public void loadValues(File file) throws IOException {
//a generic method that reads the content file to a string throwing an IOException
String line = readFileToString(file);
String[] values = line.split(";");
field1=values[0];
field2=Integer.parseInt(values[1]);
}
//then i'll have well known getters:
public String getField1() {
return field1;
}
public Integer getField2() {
return field2;
}
次に、2 番目の慣用句:
private String[] values; //made the values a class field
public void loadValues(File file) throws IOException {
//a generic method that reads the content file to a string throwing an IOException
String line = readFileToString(file);
values = line.split(";");
}
public String getField1() {
return values[0]
}
public Integer getField2() {
return Integer.parseInt(values[1]);
}
大きな違いは例外管理にあります。どちらの場合にも発生する可能性のある 2 つの実行時例外をキャッチすることを意図的に省略しました。
ArrayIndexOutOfBoundsException
ファイルに含まれるフィールドが 2 つ未満の場合NumberFormatException
整数の解析が失敗した場合
最初のアプローチ
すべてのフィールドが起動時にロードされます。そのうちの 1 つが解析可能でなくても十分ですNumberFormatException
。. 必要なフィールドよりもフィールドが少ない場合、範囲外の例外が発生します。特に、特定のフィールド値を使用するという事実の背後にあるすべてのフィールド値の正確性を確保したい場合: 高速パラダイムに失敗します。100 個のフィールドがあり、レコードにエラーが含まれており、そのエラーがトラブルシューティングのためにファイルに記録されているとします。そのまま、このコードは次のようになります。
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
つまり、エラー、エラーの原因となった値、エラーが発生した行番号を取得しますが、フィールド名は取得しません。開発者にとっては良いことですが、通常ソース コードにアクセスできないシステム エンジニアにとってはあまり良いことではありません。
2 番目のアプローチフィールドは、 getter を介してアクセスされた場合にのみ
、データ文字列から「抽出」されて解析されます。各ゲッターは、まったく同じ状況で、上記の 2 つのエラーを返す場合があります。「フェイル ファスト パラダイム」とは対照的に、ある程度の「フォールト トレランス」があります。レコードの 100 番目のフィールドに正しくない値が含まれていても、クラスのクライアントがゲッターを呼び出さない場合、例外はスローされません。一方、不正な値のゲッターが呼び出されると、ログに記録された例外には、問題の原因となったフィールドの情報が含まれます (スタック トレース内)。
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:449)
at java.lang.Integer.parseInt(Integer.java:499)
at com.test.MyReader.getField2(MyReader.java:39)
at com.test.MyReader.test(MyReader.java:33)
at com.test.MyReader.main(MyReader.java:16)
質問
どちらのアプローチにも長所と短所があり、どちらを採用するかの決定はコンテキストに依存すると言えます。質問は次のとおりです。
- ゲッターとセッターは JavaBeans のサブジェクトです。彼らが例外を返すことは「受け入れられる」のですか?
- 2 つのアプローチのクラスは、明らかに同じインターフェイスを持っている可能性がありますが、例外のアーキテクチャがまったく異なるため、クライアントはそれらをまったく異なる方法で使用することになっています。では、この事実をクライアントにどのように伝えればよいのでしょうか? ゲッターのセマンティックが誤解を招く可能性があります。おそらくもっと雄弁な方法がありますか?