Каков наилучший способ узнать, являются ли все переменные в классе нулевыми?
Это означало бы, что класс был инициализирован, но переменные не были установлены.
Пример класса:
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.
}
});
}