Java 8 provides a new way to deal with null references called Optionals. In these slides I cover why null was called the "billion dollar mistake" and how to mitigate it's damage.
3. What’s wrong with null?
• Null references were introduced in 1965 byTony Hoare while designingALGOLW.
• He thought it was the most convenient way to model the absense of a value.
• Many programming languages followed this approach.
• After many years he sees his decisión as “my billion-dollar mistake”.
8. What’s wrong with null?
• NullPointerException is one of the most common exceptions thrown in Java.
• It worsens readability.
• It’s the only thing in Java that makes pointers are not hidden.
10. Optional to the rescue
What is an Optional?
• A class that encapsulates an optional value.
• When the value is present, the Optional just wraps it.
• If the value is not present, the OptionalWill be a special singleton instance representing an empty
Optional.
Fin: Para que veamos a qué se refería, veamos un ejemplo
Imaginad que tenéis esta relación entre estas tres clases. Un cliente tiene una cuenta y cada cuenta está asociada a un método de pago. Ahora vuestro cliente os pide que creéis un método que obtenga el nombre del método de pago asociado a un cliente.
La solución más simple sería la siguiente, accediendo a cada atributo de forma escalonada.
¿Pero qué pasaría si client, getAccount() o getPaymentMethod() fuera nulo?
FIN: Una forma de solucionar este problema sería comprobar que cada atributo fuera distinto a null antes de acceder a ellos.
Como vemos, en este caso por cada “duda” que tenemos, realizamos una comprobación, comprometiendo la legibilidad y complejidad ciclomática.
Fin: Otra posibilidad que reduciría la complejidad ciclomática sería devolver el valor por defecto cada vez que nos encontremos con un posible null.
En este caso, aunque nos hemos librado de los condicionales anidados, hemos aumentado a 4 los puntos de retorno del método.
El método sigue siendo feo.
FIN: Como vemos, el uso de la referencia nula nos da ciertos quebraderos de cabeza.
ANTES DEL MEME: Por todo esto podemos decir que, uno trata con referencias nulas así como así.
Por suerte Java 8 nos ha dado una forma para mitigar el daño de la referencia nula: Los Optionals.
Un Optional en Java no es más que una clase que encapsula un valor opcional.
Si el valor está presente, simplemente lo contiene.
Si el valor en cambio no está presente, contendrá una instancia especial que representa a un valor vacío.
FIN: Y vosotros os preguntaréis ¿Cuál es la diferencia a usar null? Sigamos con el ejemplo anterior.
Partamos del ejemplo anterior. Un cliente con una cuenta y un método de pago.
¿Qué sucedería si modificamos los getters de los atributos que pueden ser nulos y hacemos que devuelvan un Optional?
Tendríamos un modelo como el siguiente.
FIN: Veamos como quedaría el código.
¿Os acordáis de este método tan feo? Haciendo uso de Optionals podremos pasar a esto.
¿Qué está sucediendo? (Explicar)
Si no habéis trabajado con Optionals, es normal que os sintáis así (Imagen de abuela), pero no os preocupéis, ahora veremos más en profundidad lo que ha sucedido.
¿Os acordáis de este método tan feo? Haciendo uso de Optionals podremos pasar a esto.
¿Qué está sucediendo? (Explicar)
Si no habéis trabajado con Optionals, es normal que os sintáis así (Imagen de abuela), pero no os preocupéis, ahora veremos más en profundidad lo que ha sucedido.
El primer paso para trabajar con Optionals es saber como crearlos.
Lo más simple es crear un Optional vacío.
Si quisiérais crear un Optional a partir de un valor que no debe ser nulo.
¿Qué pasaría myInteger fuera null? NullPointerException
¿Qué sentido tiene?¿No nos habíamos liberado de esta lacra?
Nos sirve para cuando necesitamos un objeto Optional a partir de un valor que no puede ser nulo.
Finalmente podremos crear Optionals a partir de valores que pueden o no ser nulos, en cuyo caso el valor del optional será Optional.empty().
El siguiente paso es transformar Optionals.
Si quisiéramos obtener un atributo o llamada a un método de un Optional, lo podríamos hacer mediante el método ”map”.
En este ejemplo estamos extrayendo el nombre del método de pago. Ya que estamos extrayendo un valor de un Optional, el resultado de esta operación es otro Optional.
FIN: Otra forma de modificar un Optional es transformarlo en otro Optional. Volvamos un momento al primer método con optionals que hemos visto.
Como vemos, tenemos dos llamadas a flatMap(). Con esta llamada lo que hacemos es transformar el Optional en otro Optional, en este caso específico, en el de los atributos que contiene.
¿Por qué no usar map()?
Porque map() devuelve un Optional del objeto que se devuelve, en este caso Optional<String>. Si usáramos map() sobre getAccount() el resultado sería Optional<Optional<ClientOptional>>.
FIN: Una de las partes más importantes es poder obtener el valor dentro de un Optional.
1: Para obtener el valor dentro de un Optional utilizaremos get(). Si el Optional estuviera vacío se lanzaría un NoSuchElementException
2: Si quisiéramos devolver un valor predeterminado en caso de estar vacío el Optional, utilizaremos orElse().
3: Si quisiéramos construir el valor por defecto sólo si el Optional estuviera vacío usaríamos orElseGet().
4: En caso de querer lanzar una excepción si el Optional estuviera vacío, usaremos orElseThrow.
5: Finalmente, en caso de querer ejecutar una acción determinada en caso de no estar vacío, utilizaríamos ifPresent().
FIN: Para terminar, Optional nos da la posibilidad de rechazar determinados valores.
Mediante el método filter(), podemos rechazar los valores que consideremos dentro de un Optional.
En este caso, estamos rechazando los valores impares, de modo que si myInteger fuera 11, i sería un Optional vacío.
Un caso de uso típico es la ejecución de una acción después de la obtención de un resultado, como puede ser este caso.
El fin. Si os ha gustado la presentación ya sabéis, acepto cerveza gratis.