Действительно ли возможно в Java проверить, являются ли поля объектов пустыми и затем добавляют значение по умолчанию ко всем тем атрибутам?

Я должен удостовериться, что никакой атрибут объекта не является пустым, и добавьте значение по умолчанию в случае, если, если это является пустым. Там какой-либо простой способ состоит в том, чтобы сделать это, или я должен сделать это вручную путем проверки каждого атрибута его методами считывания и методами set?

26
задан Valentin Blokhin 12 August 2016 в 09:02
поделиться

5 ответов

Вы можете использовать отражение для повторения по полям объекта и установить их. Вы, очевидно, вам нужен какой-то сопоставление между типами или даже именами полей и требует значения по умолчанию, но это можно сделать довольно легко в цикле. Например:

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 ()

39
ответ дан 28 November 2019 в 06:39
поделиться

Может быть, проверка 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.

7
ответ дан 28 November 2019 в 06:39
поделиться

Вы Надо вручную фильтровать вход в конструкторы и поселенцы. Ну ... вы могли бы использовать отражение, но я бы не советую это. Часть работы конструкторов и составляющих состоит в том, чтобы подтвердить вклад. Это может включать такие вещи, как:

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;
}

, вы можете использовать функции обертки для фактической проверки и выбрасывания исключения.

11
ответ дан 28 November 2019 в 06:39
поделиться

Можно создать функцию, которая возвращает булевое значение и проверяет каждый атрибут. Вы можете вызвать эту функцию, чтобы сделать работу за вас.

В качестве альтернативы Вы можете инициализировать объект значениями по умолчанию. Таким образом, отпадает необходимость в проверке.

0
ответ дан 28 November 2019 в 06:39
поделиться

У меня недостаточно контекста, чтобы дать вам правильный ответ, но я предлагаю вам сделать код неизменяемым как насколько это возможно. Используйте общедоступные финальные поля. Больше никаких геттеров или сеттеров : каждое поле должно быть определено конструктором . Ваш код короче, удобочитаем и не позволяет писать код с побочными эффектами.

Это не мешает вам передавать нулевые аргументы в ваш конструктор ... Вы по-прежнему можете проверять каждый аргумент, как предлагает @cletus, но я предлагаю вам выбросить IllegalArgumentException вместо NullPointerException , который не дает никаких новых намеков на то, что вы сделали.

В любом случае, это то, чем я занимаюсь, насколько могу, и это в значительной степени улучшило мой код (читаемость, стабильность). Все в моей команде так поступают, и мы очень этому довольны. Мы узнали это, когда пытаемся написать код erlang , в котором все неизменяемо.

Надеюсь, это поможет.

0
ответ дан 28 November 2019 в 06:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: