th3an0maly
Esto significaría que la clase se inicializó, pero las variables no se establecieron.
Una clase de muestra:
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;
}
}
La clase real es enorme que prefiero no comprobar. if(xyz == null)
para cada una de las variables.
didier l
Otra solución no reflectante para Java 8, en la línea de la respuesta de paxdiabo pero sin usar una serie de if
‘s, sería transmitir todos los campos y verificar la nulidad:
return Stream.of(id, name)
.allMatch(Objects::isNull);
Esto sigue siendo bastante fácil de mantener mientras evita la reflexión. martillo.
-
¿Hay alguna forma de obtener los valores de campo, por ejemplo: Stream.of (id, nombre), eliminar campos nulos y devolver la lista de valores de campos no nulos?
– Enjuague S
3 de marzo de 2018 a las 13:31
-
@Rinsen puedes usar
filter()
pero esa es una pregunta diferente y es probable que ya se haya hecho en SO.– Didier L.
3 de marzo de 2018 a las 13:39
-
gracias por el comentario, esa es una pregunta diferente, pero ¿puede decirme cómo hacerlo ya que tengo un problema y no puedo encontrar una solución eficiente? Gracias de antemano
– Enjuague S
3 de marzo de 2018 a las 14:32
arshajii
Prueba algo como esto:
public boolean checkNull() throws IllegalAccessException {
for (Field f : getClass().getDeclaredFields())
if (f.get(this) != null)
return false;
return true;
}
Aunque probablemente sería mejor verificar cada variable si es factible.
-
En cuanto al rendimiento, ¿está tan por detrás del
if(variable==null)
¿método?– th3an0maly
12 de septiembre de 2012 a las 10:07
-
Sí, es probable que tome mucho más tiempo que
if (var == null)
.– arshajii
12/09/2012 a las 11:00
-
@Yar, para que esto funcione para campos privados, debe hacer f.setAccessible(true)
– Jawa
22/03/2018 a las 18:30
-
el uso de la reflexión es bastante lento, oculta mucho de lo que realmente se hace y, en un pensamiento más general, puede ser una molestia refactorizar (un campo puede marcarse como no utilizado por su IDE cuando en realidad es a través de la reflexión: / y lo hará nunca se sabe que realmente se usó a menos que tenga buenas pruebas o ejecute su aplicación) Por supuesto, esto no prohíbe usar la reflexión, pero si puede usar cualquier otra opción … hágalo
– minioim
8 de agosto de 2019 a las 13:03
-
Nunca será demasiado decir que necesita agregar
f.setAccessible(true)
para evitar IllegalAccessException en campos privados.– Ara Kokeba
21 de noviembre de 2019 a las 20:03
Martín Tarjányi
Esto se puede hacer con bastante facilidad utilizando un Lombok generado equals
y una estática EMPTY
objeto:
import lombok.Data;
public class EmptyCheck {
public static void main(String[] args) {
User user1 = new User();
User user2 = new User();
user2.setName("name");
System.out.println(user1.isEmpty()); // prints true
System.out.println(user2.isEmpty()); // prints false
}
@Data
public static class User {
private static final User EMPTY = new User();
private String id;
private String name;
private int age;
public boolean isEmpty() {
return this.equals(EMPTY);
}
}
}
requisitos previos:
- El constructor predeterminado no debe implementarse con un comportamiento personalizado, ya que se usa para crear el
EMPTY
objeto - Todos los campos de la clase deben tener un implementado
equals
(Los tipos de Java incorporados generalmente no son un problema, en el caso de tipos personalizados, puede usar Lombok)
Ventajas:
- No hay reflexión involucrada
- Como se agregaron nuevos campos a la clase, esto no requiere ningún mantenimiento ya que debido a Lombok, se verificarán automáticamente en el
equals
implementación - A diferencia de otras respuestas, esto funciona no solo para comprobaciones nulas, sino también para tipos primitivos que tienen un valor predeterminado no nulo (por ejemplo, si el campo es
int
lo comprueba0
en caso deboolean
porfalse
etc.)
-
Esto creará un objeto extra.
EMPTY
junto con cada objeto. ¿Afectará esto al rendimiento?– Sp4RX
5 de marzo de 2019 a las 0:34
-
Vacío es un campo estático aquí, por lo que no debería ser un problema.
– Martín Tarjányi
25 de julio de 2019 a las 17:13
-
@MartinTarjányi pero el método equals() en java compara instancias y no sus valores de campo. Deberá anular equals() y hashCode().
– Tamim Attafi
15 de enero de 2020 a las 6:09
-
por eso usé la anotación lombok
– Martín Tarjányi
15 de enero de 2020 a las 6:10
Si quieres esto para pruebas unitarias, solo uso el hasNoNullFieldsOrProperties()
método de assertj
assertThat(myObj).hasNoNullFieldsOrProperties();
¿Qué hay de las corrientes?
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.
}
});
}
-
esto no es escalable.
– saran3h
30 oct 2021 a las 6:15
paxdiablo
“Mejor” es un término tan subjetivo 🙂
Simplemente usaría el método de verificar cada variable individual. Si su clase ya tiene muchos de estos, el aumentar en tamaño no va a ser tanto si haces algo como:
public Boolean anyUnset() {
if ( id == null) return true;
if (name == null) return true;
return false;
}
Siempre que mantenga todo en el mismo orden, los cambios de código (y la verificación automática con un script si está paranoico) serán relativamente sencillos.
Alternativamente (asumiendo que son todas cadenas), básicamente podría poner estos valores en un mapa de algún tipo (por ejemplo, HashMap
) y solo mantenga una lista de los nombres clave para esa lista. De esa manera, podría iterar a través de la lista de claves, verificando que los valores estén configurados correctamente.
-
esto no es escalable.
– saran3h
30 oct 2021 a las 6:15
Creo que esta es una solución que resuelve su problema fácilmente: (devuelve verdadero si alguno de los parámetros no es nulo)
public boolean isUserEmpty(){
boolean isEmpty;
isEmpty = isEmpty = Stream.of(id,
name)
.anyMatch(userParameter -> userParameter != null);
return isEmpty;}
Otra solución para la misma tarea es: (puede cambiarlo a if (isEmpty==0) comprueba si todos los parámetros son nulos.
public boolean isUserEmpty(){
long isEmpty;
isEmpty = Stream.of(id,
name)
.filter(userParameter -> userParameter != null).count();
return isEmpty > 0
}
if(id == null)
es el mejor método.– KV Prajapati
11 de septiembre de 2012 a las 3:13
Los campos de referencia se inicializan a su valor predeterminado,
null
en ausencia de un inicializador explícito.– obataku
11 de septiembre de 2012 a las 3:21