できるJavaチェックがオ分野はnullを追加してデフォルト値がすべての属性?
質問
が必要になっていることを確認くださいオブジェクトの属性がnullの場合、追加のデフォルト値の場合の場合はnullになります。がありますをすることが、いか手動で確認べての属性によるそのsetterか、セッター?
解決
あなたは、オブジェクトのフィールドを反復処理するためにリフレクションを使用し、それらを設定することができます。あなたは明らかタイプまたは偶数フィールド名と必要な既定値との間のマッピングのいくつかの並べ替えを必要とするだろうが、これはループの中で非常に簡単に行うことができます。たとえばます:
for (Field f : obj.getClass().getFields()) {
f.setAccessible(true);
if (f.get(obj) == null) {
f.set(obj, getDefaultValueForType(f.getType()));
}
}
の [更新] の
は、現代のJavaを使用すると、クラスごとにフィールドのデフォルト値を設定するために注釈を使用することができます。完全な実装は次のようになります。
// DefaultString.java:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface DefaultString {
String value();
}
// DefaultInteger.java:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface DefaultInteger {
int value();
}
// DefaultPojo.java:
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
public class DefaultPojo {
public void setDefaults() {
for (Field f : getClass().getFields()) {
f.setAccessible(true);
try {
if (f.get(this) == null) {
f.set(this, getDefaultValueFromAnnotation(f.getAnnotations()));
}
} catch (IllegalAccessException e) { // shouldn't happen because I used setAccessible
}
}
}
private Object getDefaultValueFromAnnotation(Annotation[] annotations) {
for (Annotation a : annotations) {
if (a instanceof DefaultString)
return ((DefaultString)a).value();
if (a instanceof DefaultInteger)
return ((DefaultInteger)a).value();
}
return null;
}
}
// Test Pojo
public class TestPojo extends DefaultPojo {
@DefaultString("Hello world!")
public String stringValue;
@DefaultInteger(42);
public int integerValue;
}
次にTestPojo
のデフォルト値は、単に実行することによって設定することができますtest.setDetaults()
他のヒント
あなたは、コンストラクタとセッターへのフィルタ入力を手動でする必要があります。うーん...あなたは、リフレクションを使用することができますが、私はそれをお勧めしません。コンストラクタとセッターの仕事の一部は、入力を検証することです。それはのようなものを含めることができます:
public void setPrice(double price) {
if (price < 0.0d) {
throw new IllegalArgumentException("price cannot be negative " + price);
}
this.price = price;
}
と
public void setName(String name) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
}
あなたは、実際のチェックと例外をスローするためにラッパー関数を使用することができます。
もチェック Hibernate Validator4.0, リファレンス実装では、の JSR303:豆の検証.
この例は注釈付きのクラス:
public class Address {
@NotNull
private String line1;
private String line2;
private String zip;
private String state;
@Length(max = 20)
@NotNull
private String country;
@Range(min = -2, max = 50, message = "Floor out of range")
public int floor;
...
}
のための紹介を参照 にもかかわらずJSR303(豆の検証)–第1部 や 第2部 または、"はじめに"を参考ガイドはHibernateのバリデータ。
Javaの8のための非反射ソリューションは、場合の一連のを使用せずに、すべてのフィールドをストリーミングし、nullであるかどうかをチェックするために、次のようになります。
return Stream.of(id, name).allMatch(Objects::isNull);
これは非常に簡単反射ハンマーを回避しながら維持したまま。 これはヌル属性のtrueを返します。
あなたはブール値をチェックすべての属性を返す関数を作成することができます。あなたはあなたのための仕事をするために、その関数を呼び出すことができます。
また、あなたはデフォルト値でオブジェクトを初期化することができます。そのように、あなたがどんなチェックを行うための必要はありません。
私はあなたに正しい答えを与えるために十分なコンテキストを持っていないが、私は可能な限り、あなたのコードの不変のを作るためにあなたをお勧めします。使用public final
フィールド。これ以上getters
またはsetters
:すべてのフィールドはconstructor
で定義する必要がありません。あなたのコードは、より読みやすく短く、副作用を持つコードを書いてから防止できます。
それはあなたがまだすべての引数を確認することができますが...あなたのコンストラクタにヌル引数を渡すのを防ぐことはできませんが、私はノー与えない代わりにIllegalArgumentException
のNullPointerException
をスローするようにあなたをお勧めしますあなたが何をやったかについての新しいヒントます。
とにかく、私は同じくらい私はできる限りやるものだと、それは偉大に私のコード(読みやすさ、安定性)を改善している拡張。私のチームの誰もがそうすると、我々はそれで非常に満足しています。我々はすべてが不変であるいくつかのerlang
コードを記述しようとすることを学びました。
希望このことができます。
私はこれを試してみましたが、フィールドが空の場合には、検証するために何の問題もなく動作します。 私は個人的属性にデフォルト値を追加するために試したことがないように私は部分的にあなたの質問に答えています。
if(field.getText()!= null && !field.getText().isEmpty())
希望は、それが役立ちます。
これはヌルをチェックするためにではなく、代わりに、これは空のオブジェクト(新鮮なオブジェクト)に既存のオブジェクトを変換する際に役立つであろう。私はこれが関連しているかどうか知らないが、私はそのような要求を持っています。
@SuppressWarnings({ "unchecked" })
static void emptyObject(Object obj)
{
Class c1 = obj.getClass();
Field[] fields = c1.getDeclaredFields();
for(Field field : fields)
{
try
{
if(field.getType().getCanonicalName() == "boolean")
{
field.set(obj, false);
}
else if(field.getType().getCanonicalName() == "char")
{
field.set(obj, '\u0000');
}
else if((field.getType().isPrimitive()))
{
field.set(obj, 0);
}
else
{
field.set(obj, null);
}
}
catch(Exception ex)
{
}
}
}