verificar variable validar una objeto nulo igual diferente comprobar java syntax null variable-assignment method-call

java - variable - Compruebe si el valor devuelto no es nulo y, si es así, asigne, en una línea, con una llamada de método



variable igual a null en java (8)

Java está llena de afirmaciones como:

if(cage.getChicken() != null) { dinner = cage.getChicken(); } else { dinner = getFreeRangeChicken(); }

Lo que requiere dos llamadas a getChicken() antes de que el objeto devuelto pueda asignarse a la dinner .

Esto también podría escribirse en una línea así:

dinner = cage.getChicken() != null? cage.getChicken() : getFreeRangeChicken();

Pero, por desgracia, todavía hay dos llamadas a getChicken() .

Por supuesto, podríamos asignar una variable local y luego usar el operador ternario de nuevo para asignarla si no es nulo, pero esto es dos líneas y no es tan bonito:

FutureMeal chicken = cage.getChicken(); dinner = chicken != null? chicken : getFreeRangeChicken();

Entonces, ¿hay alguna manera de decir:

Variable var = algún valor si algún valor no es nulo O algún otro valor;

Y supongo que solo estoy hablando de sintaxis aquí, después de compilar el código, probablemente no haga mucha diferencia en cómo se escribió el código en un sentido de rendimiento.

Dado que este es un código tan común, sería genial tener una sola línea para escribirlo.

¿Algún otro idioma tiene esta característica?


Usa los tuyos

public static <T> T defaultWhenNull(@Nullable T object, @NonNull T def) { return (object == null) ? def : object; }

Ejemplo:

defaultWhenNull(getNullableString(), "");

Ventajas

  • Funciona si no desarrollas en Java8.
  • Funciona para el desarrollo de Android con soporte para dispositivos pre API 24
  • No necesita una biblioteca externa.

Desventajas

  • Siempre evalúa el default value (como se opone a cond ? nonNull() : notEvaluated() )

    Esto podría evitarse pasando un valor invocable en lugar de un valor predeterminado, pero haciéndolo un poco más complicado y menos dinámico (por ejemplo, si el rendimiento es un problema).

    Por cierto, encuentras la misma desventaja cuando usas Optional.orElse() ;-)


De forma alternativa, en Java8 puede usar anotaciones de Nullable o NotNull según sus necesidades.

public class TestingNullable { @Nullable public Color nullableMethod(){ //some code here return color; } public void usingNullableMethod(){ // some code Color color = nullableMethod(); // Introducing assurance of not-null resolves the problem if (color != null) { color.toString(); } } }

public class TestingNullable { public void foo(@NotNull Object param){ //some code here } ... public void callingNotNullMethod() { //some code here // the parameter value according to the explicit contract // cannot be null foo(null); } }

http://mindprod.com/jgloss/atnullable.html


Desde Java 9 tienes Objects#requireNonNullElse que hace:

public static <T> T requireNonNullElse(T obj, T defaultObj) { return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj"); }

Tu codigo seria

dinner = Objects.requireNonNullElse(cage.getChicken(), getFreeRangeChicken());

Que es 1 línea y llama a getChicken() solo una vez, por lo que se cumplen ambos requisitos.

Tenga en cuenta que el segundo argumento tampoco puede ser null ; este método obliga a no anular el valor devuelto.

Considera también los Objects#requireNonNullElseGet alternativos Objects#requireNonNullElseGet :

public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)

que ni siquiera evalúa el segundo argumento si el primero no es null , pero tiene la sobrecarga de crear un Supplier .


Java carece de operador de fusión, por lo que su código con un temporal explícito es su mejor opción para una asignación con una sola llamada.

Puedes usar la variable de resultado como tu temporal, así:

dinner = ((dinner = cage.getChicken()) != null) ? dinner : getFreeRangeChicken();

Esto, sin embargo, es difícil de leer.


Mismo principio que la respuesta de Loki pero más breve. Solo tenga en cuenta que más corto no significa automáticamente mejor.

dinner = Optional.ofNullable(cage.getChicken()) .orElse(getFreerangeChicken());

Nota: Este uso de Optional está explícitamente desaconsejado por los arquitectos del JDK y los diseñadores de la característica Opcional. Usted está asignando un objeto nuevo y lo tira de inmediato de inmediato. Pero por otro lado puede ser bastante legible.



Usando Java 1.8 puedes usar Optional

public class Main { public static void main(String[] args) { //example call, the methods are just dumb templates, note they are static FutureMeal meal = getChicken().orElse(getFreeRangeChicken()); //another possible way to call this having static methods is FutureMeal meal = getChicken().orElseGet(Main::getFreeRangeChicken); //method reference //or if you would use a Instance of Main and call getChicken and getFreeRangeChicken // as nonstatic methods (assume static would be replaced with public for this) Main m = new Main(); FutureMeal meal = m.getChicken().orElseGet(m::getFreeRangeChicken); //method reference //or FutureMeal meal = m.getChicken().orElse(m.getFreeRangeChicken()); //method call } static Optional<FutureMeal> getChicken(){ //instead of returning null, you would return Optional.empty() //here I just return it to demonstrate return Optional.empty(); //if you would return a valid object the following comment would be the code //FutureMeal ret = new FutureMeal(); //your return object //return Optional.of(ret); } static FutureMeal getFreeRangeChicken(){ return new FutureMeal(); } }

Implementarías una lógica para que getChicken devuelva Optional.empty() lugar de null, o Optional.of(myReturnObject) , donde myReturnObject es tu chicken .

Luego puede llamar a getChicken() y, si regresa a Optional.empty() el orElse(fallback) le daría lo que fuera a la alternativa, en su caso, el segundo método.


dinner = cage.getChicken(); if(dinner == null) dinner = getFreeRangeChicken();

o

if( (dinner = cage.getChicken() ) == null) dinner = getFreeRangeChicken();