Я должен удостовериться, что никакой атрибут объекта не является пустым, и добавьте значение по умолчанию в случае, если, если это является пустым. Там какой-либо простой способ состоит в том, чтобы сделать это, или я должен сделать это вручную путем проверки каждого атрибута его методами считывания и методами set?
Вы можете использовать отражение для повторения по полям объекта и установить их. Вы, очевидно, вам нужен какой-то сопоставление между типами или даже именами полей и требует значения по умолчанию, но это можно сделать довольно легко в цикле. Например:
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;
}
Тогда значения по умолчанию для A TestPojo
могут быть установлены только с помощью Test.SetDetaults ()
Может быть, проверка Hibernate Validator 4.0 , эталонная реализация JSR 303: проверка бобов .
Это пример аннотированного класса:
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;
...
}
для введения, см. Начало работы с JSR 303 (валидация бобов) - часть 1 и Часть 2 или Начало работы «Раздел справочного руководства, которое является частью распределения Hibernate Validator.
Вы Надо вручную фильтровать вход в конструкторы и поселенцы. Ну ... вы могли бы использовать отражение, но я бы не советую это. Часть работы конструкторов и составляющих состоит в том, чтобы подтвердить вклад. Это может включать такие вещи, как:
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;
}
, вы можете использовать функции обертки для фактической проверки и выбрасывания исключения.
Можно создать функцию, которая возвращает булевое значение и проверяет каждый атрибут. Вы можете вызвать эту функцию, чтобы сделать работу за вас.
В качестве альтернативы Вы можете инициализировать объект значениями по умолчанию. Таким образом, отпадает необходимость в проверке.
У меня недостаточно контекста, чтобы дать вам правильный ответ, но я предлагаю вам сделать код неизменяемым как насколько это возможно. Используйте общедоступные финальные
поля. Больше никаких геттеров
или сеттеров
: каждое поле должно быть определено конструктором
. Ваш код короче, удобочитаем и не позволяет писать код с побочными эффектами.
Это не мешает вам передавать нулевые аргументы в ваш конструктор ... Вы по-прежнему можете проверять каждый аргумент, как предлагает @cletus, но я предлагаю вам выбросить IllegalArgumentException
вместо NullPointerException
, который не дает никаких новых намеков на то, что вы сделали.
В любом случае, это то, чем я занимаюсь, насколько могу, и это в значительной степени улучшило мой код (читаемость, стабильность). Все в моей команде так поступают, и мы очень этому довольны. Мы узнали это, когда пытаемся написать код erlang
, в котором все неизменяемо.
Надеюсь, это поможет.