Una de las características importantes que se introdujeron con Java SE 14 fue NullPointerExceptions útiles , que está relacionada con la usabilidad de NullPointerException . ¿Qué hace que NullPointerException en Java SE 14 sea más útil que su predecesor?
La JVM lanza una NullPointerException en el punto de un programa donde el código intenta desreferenciar una referencia null . Con Java SE 14, NullPointerException ofrece información útil sobre la terminación prematura de un programa. Java SE 14 en adelante, la JVM describe la variable (en términos de código fuente) con un mensaje de detalle nulo en NullPointerException . Mejora en gran medida la comprensión del programa al asociar más claramente una excepción dinámica con el código del programa estático.
Podemos ver la diferencia con un ejemplo.
import java.util.ArrayList; import java.util.List; class Price { double basePrice; double tax; public Price() { } public Price(double basePrice) { this.basePrice = basePrice; } public Price(double basePrice, double tax) { this.basePrice = basePrice; this.tax = tax; } // ... } class Product { String name; Price price; public Product() { } public Product(String name, Price price) { this.name = name; this.price = price; } // ... } class CartEntry { Product product; int quantity; public CartEntry() { } public CartEntry(Product product, int quantity) { this.product = product; this.quantity = quantity; } // ... } class Cart { String id; List<CartEntry> cartEntries; public Cart() { cartEntries = new ArrayList<>(); } public Cart(String id) { this(); this.id = id; } void addToCart(CartEntry entry) { cartEntries.add(entry); } // ... } public class Main { public static void main(String[] args) { Cart cart = new Cart("XYZ123"); cart.addToCart(new CartEntry()); System.out.println(cart.cartEntries.get(0).product.price.basePrice); } } Exception in thread "main" java.lang.NullPointerException at Main.main(Main.java:74) Este mensaje deja al programador sin idea sobre el origen de NullPointerException .
Exception in thread "main" java.lang.NullPointerException: Cannot read field "price" because "java.util.List.get(int).product" is null at Main.main(Main.java:74) La NullPointerException en Java SE 14 también nos dice qué referencia es null .
¡Una gran mejora!
Está documentado en las notas de la versión.
El nuevo mensaje no se muestra de forma predeterminada en la versión 1.14:
Hay una nueva opción disponible para proporcionar mensajes NullPointerException más útiles:
-XX:+MostrarDetallesDeCódigoEnMensajesDeExcepción
Si la opción está configurada, al encontrar un puntero nulo, la JVM analiza el programa para determinar qué referencia era nula y luego proporciona los detalles como parte de NullPointerException.getMessage(). Además del mensaje de excepción, también se devuelven el método, el nombre de archivo y el número de línea.
Por defecto, esta opción está deshabilitada.
y la propuesta completa JEP 358 para motivación.
Finalmente
El valor predeterminado de la bandera ShowCodeDetailsInExceptionMessages se cambió a 'verdadero'.
Cuando la JVM lanza una NullPointerException , ahora agrega un mensaje de detalle que especifica qué referencia era nula.
Esto hace que el seguimiento de la pila sea más fácil de interpretar y resuelve la ambigüedad si el programa accede a varias referencias en la misma línea en el código fuente. Por ejemplo, la línea
person.name = student.name; lanza una NullPointerException si person o student es null , pero antes de Java 14, la excepción no nos decía cuál era. Ahora, lo hace:
java.lang.NullPointerException: no se puede leer el campo "nombre" porque "estudiante" es nulo
Más información sobre este cambio está disponible en JEP-358 .