Llego tarde al juego, pero por lo que vale, quiero agregar mis 2 centavos. Van en contra del objetivo de diseño deOptional
, que está bien resumido por la respuesta de Stuart Marks , pero todavía estoy convencido de su validez (obviamente).
Usar opcional en todas partes
En general
Escribí una publicación de blogOptional
completa sobre el uso, pero básicamente se reduce a esto:
- diseñe sus clases para evitar la opcionalidad siempre que sea posible
- en todos los casos restantes, el valor predeterminado debería ser usar en
Optional
lugar denull
- posiblemente hacer excepciones para:
- variables locales
- devolver valores y argumentos a métodos privados
- bloques de código de rendimiento crítico (sin adivinanzas, use un generador de perfiles)
Las dos primeras excepciones pueden reducir la sobrecarga percibida de envolver y desenvolver referencias en Optional
. Se eligen de manera que un valor nulo nunca pueda pasar legalmente un límite de una instancia a otra.
Tenga en cuenta que esto casi nunca permitirá Optional
s en colecciones que es casi tan malo como null
s. Solo no lo hagas. ;)
Con respecto a sus preguntas
- Si.
- Si la sobrecarga no es una opción, sí.
- Si otros enfoques (subclases, decoración, ...) no son una opción, sí.
- ¡Por favor no!
Ventajas
Hacer esto reduce la presencia de null
s en su base de código, aunque no los erradica. Pero ese ni siquiera es el punto principal. Hay otras ventajas importantes:
Aclara la intención
El uso Optional
expresa claramente que la variable es, bueno, opcional. Cualquier lector de su código o consumidor de su API será derrotado con el hecho de que podría no haber nada allí y que es necesario realizar una verificación antes de acceder al valor.
Elimina la incertidumbre
Sin Optional
el significado de un null
hecho no está claro. Podría ser una representación legal de un estado (ver Map.get
) o un error de implementación como una inicialización faltante o fallida.
Esto cambia dramáticamente con el uso persistente de Optional
. Aquí, ya la aparición de null
significa la presencia de un error. (Porque si se permitiera que faltara el valor, Optional
se habría utilizado un.) Esto hace que la depuración de una excepción de puntero nulo sea mucho más fácil ya que la pregunta sobre el significado de esto null
ya está respondida.
Más cheques nulos
Ahora que nada puede ser null
más, esto puede hacerse cumplir en todas partes. Ya sea con anotaciones, aserciones o comprobaciones simples, nunca tendrá que pensar si este argumento o ese tipo de retorno pueden ser nulos. No puede!
Desventajas
Por supuesto, no hay bala de plata ...
Actuación
Ajustar los valores (especialmente los primitivos) a una instancia adicional puede degradar el rendimiento. En lazos cerrados, esto podría volverse notable o incluso peor.
Tenga en cuenta que el compilador podría evitar la referencia adicional para vidas cortas de Optional
s. En Java 10 , los tipos de valor pueden reducir o eliminar aún más la penalización.
Publicación por entregas
Optional
no es serializable, pero una solución alternativa no es demasiado complicada.
Invariancia
Debido a la invariabilidad de los tipos genéricos en Java, ciertas operaciones se vuelven engorrosas cuando el tipo de valor real se inserta en un argumento de tipo genérico. Aquí se da un ejemplo (ver "Polimorfismo paramétrico") .
Map<Character, String>
. Si no hay una sustitución puedo usar esto:Optional.ofNullable(map.get(c)).orElse(String.valueOf(c))
. También tenga en cuenta que Opcional fue robado de Guava y tiene una sintaxis mucho mejor:Optional.fromNullable(map.get(c)).or(String.valueOf(c));