Каков наилучший способ узнать, являются ли все переменные в классе нулевыми?

Это означало бы, что класс был инициализирован, но переменные не были установлены.

Пример класса:

public class User {

    String id = null;
    String name = null;

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

Фактический класс огромен, и я предпочитаю не проверять, есть ли (xyz == null) для каждой из переменных.

Ответ 1

Попробуйте что-то вроде этого:

public boolean checkNull() throws IllegalAccessException {
    for (Field f : getClass().getDeclaredFields())
        if (f.get(this) != null)
            return false;
    return true;            
}

Хотя, вероятно, было бы лучше проверить каждую переменную, если это вообще возможно.

Ответ 2

Еще одно неотражающее решение для Java 8, в строке paxdiabo answer, но без использования серии if, должно было бы передать все поля и проверьте значение nullness:

return Stream.of(id, name)
        .allMatch(Objects::isNull);

Это остается довольно легко поддерживать, избегая отражения.

Ответ 3

"Лучший" - такой субъективный термин: -)

Я бы просто использовал метод проверки каждой отдельной переменной. Если у вашего класса уже много таких, увеличение размера не будет таким большим, если вы сделаете что-то вроде:

public Boolean anyUnset() {
    if (  id == null) return true;
    if (name == null) return true;
    return false;
}

Если вы храните все в одном порядке, изменения кода (и автоматическая проверка с помощью script, если вы параноидальные) будут относительно безболезненными.

В качестве альтернативы (при условии, что они все строки) вы могли бы поместить эти значения в какую-либо карту (например, HashMap) и просто сохранить список имен ключей для этого списка. Таким образом, вы можете перебирать список ключей, проверяя правильность установки значений.

Ответ 4

Это также можно сделать без использования отражения.

Решение является динамическим. Когда ваш класс расширен с новыми полями, вам не нужно добавлять их в список или добавлять еще одну нулевую проверку.

Примечание:

Я использовал аннотацию EqualsAndHashCode от Lombok.

Вы должны убедиться, что конструктор по умолчанию не реализован с пользовательским поведением, а ваши поля не имеют значения по умолчанию, отличного от встроенного значения java по умолчанию (null для ссылочных типов, 0 для int и т.д.).

@EqualsAndHashCode
public class User
{
    private static User EMPTY = new User();

    private String id = null;
    private String name = null;

    private User()
    {
    }

    public User(String id, String name)
    {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public boolean isEmpty()
    {
        return this.equals(EMPTY);
    }
}

Ответ 5

Field[] field = model.getClass().getDeclaredFields();     

for(int j=0 ; j<field.length ; j++){    
            String name = field[j].getName();                
            name = name.substring(0,1).toUpperCase()+name.substring(1); 
            String type = field[j].getGenericType().toString();    
            if(type.equals("class java.lang.String")){   
                Method m = model.getClass().getMethod("get"+name);
                String value = (String) m.invoke(model);    
                if(value == null){
                   ... something to do...
                }
}

Ответ 6

На мой взгляд, лучший способ - это рефлексия, как рекомендовали другие. Вот пример, который оценивает каждое локальное поле для нуля. Если он найдет значение, отличное от null, метод вернет false.

public class User {

    String id = null;
    String name = null;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isNull() {
        Field fields[] = this.getClass().getDeclaredFields();
        for (Field f : fields) {
            try {
                Object value = f.get(this);
                if (value != null) {
                    return false;
                }
            }
            catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


        }
        return true;

    }

    public static void main(String args[]) {
        System.out.println(new User().isNull());
    }
}

Ответ 7

Как насчет потоков?

public boolean checkFieldsIsNull(Object instance, List<String> fieldNames) {

    return fieldNames.stream().allMatch(field -> {
        try {
            return Objects.isNull(instance.getClass().getDeclaredField(field).get(instance));
        } catch (IllegalAccessException | NoSuchFieldException e) {
            return true;//You can throw RuntimeException if need.
        }
    });
}