¿Por qué usar Opcional.

232

Cuando se usa la Optionalclase Java 8 , hay dos formas en que un valor se puede ajustar de forma opcional.

String foobar = <value or null>;
Optional.of(foobar);         // May throw NullPointerException
Optional.ofNullable(foobar); // Safe from NullPointerException

Entiendo que Optional.ofNullablees la única forma segura de usar Optional, pero ¿por qué Optional.ofexiste? ¿Por qué no solo usar Optional.ofNullable y estar seguro en todo momento?

torbellino
fuente
1
dígame qué paquete debe importar para usar esto.
LoveToCode
44
@LoveToCode java.util.Optional: está disponible si está utilizando JDK 8 o posterior
whirlwin
11
Me encantaría que hubieran ofNullable()nombrado of()y of()nombradoofNotNull()
Robert Niestroj
Consulte baeldung.com/java-optional
Sumesh TG el
Como se está preguntando "¿por qué existe Optional.of en absoluto? ¿Por qué no solo usar Optional.ofNullable y estar seguro en todo momento?" Digamos que si los datos requeridos por el usuario no están presentes, debemos lanzar una excepción. Por lo tanto, depende totalmente de su caso de uso. baeldung.com/java-optional-throw-exception
Karan Arora

Respuestas:

306

Su pregunta se basa en la suposición de que el código que puede arrojar NullPointerExceptiones peor que el código que no puede arrojar . Esta suposición está mal. Si espera que foobarnunca sea nulo debido a la lógica del programa, es mucho mejor usarlo, Optional.of(foobar)ya que verá una NullPointerExceptionque indicará que su programa tiene un error. Si lo usa Optional.ofNullable(foobar)y foobarse nulldebe al error, su programa continuará funcionando incorrectamente en silencio, lo que puede ser un desastre mayor. De esta manera, un error puede ocurrir mucho más tarde y sería mucho más difícil de entender en qué momento salió mal.

Tagir Valeev
fuente
129129
" Si esperas que tu foobar nunca sea nulo debido a la lógica del programa, es mucho mejor usarloOptional.of(foobar) ". Esto parece un poco extraño: cuando sabemos que el valor no será nullen ningún caso, ¿por qué no usar el valor en sí mismo, en lugar de envolverlo dentro de un Optional?
Konstantin Yovkov
54
@kocko, es posible que deba devolver el Optionalmétodo según lo requiera la interfaz que está implementando (probablemente otros implementadores pueden devolver una opción vacía). O desea crear una colección / secuencia de opciones, algunas de las cuales están garantizadas como no nulas y otras no. O tiene una lógica condicional que crea un opcional en varias ramas y en una sola rama está seguro de que no es nulo.
Tagir Valeev
28
Porque Opcional significa que puede estar presente o ausente. Ausente! = Nulo. nullen este caso significa "Espero que foobar esté presente, pero debido a un error es nulo". Optional.isPresent() == falsesignifica que foobar no está presente, es decir, esto se espera, comportamiento legítimo.
Buurman
43
@kocko: ejemplo sencillo: return list.isEmpty()? Optional.empty(): Optional.of(list.get(0));la listse espera que no contienen nullvalores ...
Holger
55
@Harish si me preguntas, no te aconsejo usar los opcionales en todas partes. Esa es una pregunta separada. Puede consultar algunas opiniones aquí .
Tagir Valeev
12

Además, si sabe que su código no debería funcionar si el objeto es nulo, puede lanzar una excepción utilizando Optional.orElseThrow

String nullName = null;
String name = Optional.ofNullable(nullName).orElseThrow(NullPointerException::new);
Karan Arora
fuente
1
Pero para esto, puedes usar el aún más cortoString name = Objects.requireNonNull(nullName);
Holger,
1
Buen punto @Holger, sin embargo, el método .orElse () permite excepciones personalizadas que podrían ayudarlo a manejar mejor el flujo de control o el registro de información.
Nikos Stais
1
Bueno, puede proporcionar un mensaje para la excepción para dar información adicional. Cualquier otro intento de personalización, como usar una excepción diferente de NullPointerExceptioncuando el problema es claramente una referencia que es, nullaunque no debería, sería un paso en la dirección equivocada.
Holger
también, puede usar Opcional para lanzar una excepción más específica (por ejemplo, personalizada), no NPE, NPE es demasiado genérico, puede lanzar algo comonew NullNameException("meaningful msg")
Dáve
1

Esto depende de los escenarios.

Digamos que tiene alguna funcionalidad comercial y necesita procesar algo con ese valor aún más, pero tener nullvalor en el momento del procesamiento lo afectaría.

Entonces, en ese caso, puedes usar Optional<?>.

String nullName = null;

String name = Optional.ofNullable(nullName)
                      .map(<doSomething>)
                      .orElse("Default value in case of null");
Gautam Chaurasia
fuente
0

Opcional debe usarse principalmente para resultados de Servicios de todos modos. En el servicio, sabe lo que tiene a mano y devuelve Opcional.of (someValue) si tiene un resultado y devuelve Opcional.empty () si no lo tiene. En este caso, algún valor nunca debe ser nulo y aún así, devuelve un Opcional.

espendennis
fuente
1
Gracias por la edición de Sumesh, pero el "someValue" en la última línea que editó para ser "some Value", hace referencia a la variable en "Opcional.of (someValue)" anterior y creo que debería ser someValue.
espendennis