Java14中的NullPointerException与其前身有何不同?
Java SE 14 引入的重要特性之一是Helpful NullPointerExceptions,它与NullPointerException. 是什么让NullPointerExceptionJava SE 14 比它的前身更有用?
回答
JVMNullPointerException在程序中的代码试图取消引用引用的点处抛出一个null。Java SE 14NullPointerException提供了有关程序提前终止的有用信息。的Java SE 14起,JVM描述了变量(在源代码而言)与空详细消息中NullPointerException。它通过更清晰地将动态异常与静态程序代码相关联,极大地提高了程序理解。
让我们通过一个例子来看看区别。
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);
}
}
Java SE 14 之前的输出:
Exception in thread "main" java.lang.NullPointerException
at Main.main(Main.java:74)
此消息使程序员对NullPointerException.
Java SE 14 以上的输出:
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)
将NullPointerException在Java SE 14还告诉我们,这是参考null。
一个很大的改进!
- The "premature termination" isn't relevant. The information is still there if you catch it instead.
- It is vague and inaccurate to imply that exceptions cause "premature termination of the program". Yes, *uncaught* exceptions cause the *thread* to complete abruptly, but that only terminates the program if it was the last non-daemon thread alive. And even if the program chooses to terminate, this doesn't imply a lack of maturity.
- Oh, and *objects* can't be null. Only *references* can be.
回答
它记录在发行说明中。
默认情况下,1.14 版中不显示新消息:
JDK 14 中的新增功能
一个新选项可用于提供更有用的 NullPointerException 消息:
-XX:+ShowCodeDetailsInExceptionMessages
如果设置了该选项,则在遇到空指针时,JVM 会分析程序以确定哪个引用为空,然后将详细信息作为 NullPointerException.getMessage() 的一部分提供。除了异常消息之外,还会返回方法、文件名和行号。
默认情况下,此选项处于禁用状态。
以及用于激励的完整提案JEP 358。
最终
JDK 15 中的新增功能
标志 ShowCodeDetailsInExceptionMessages 的默认值已更改为“true”。
回答
当 JVM 抛出 时NullPointerException,它现在会添加一条详细消息,指定哪个引用为空。
这使得堆栈跟踪更易于解释,并在程序访问源代码中同一行上的多个引用时解决歧义。例如,线
person.name = student.name;
抛出NullPointerExceptionifperson或studentis null,但在 Java 14 之前,异常并没有告诉我们它是哪个。现在,它确实:
java.lang.NullPointerException:无法读取字段“名称”,因为“学生”为空
JEP-358 中提供了有关此更改的更多信息。