在文章“ 更好的默认NullPointerException消息是否会传入Java? ”,我总结了当时与JEP 草案有关的背景细节,有关使某些类型的NullPointerException (NPE)消息更有用。 上周很高兴看到该JEP现在是候选 JEP ( JEP 358 :“ Helpful NullPointerExceptions”)。 在这篇文章中,我重点介绍了JEP 358的一些特别有趣的方面。
什么是JEP 358?
JEP 358的当前“摘要”简要描述了此JEP:“通过准确描述哪个变量为null
,提高JVM生成的NullPointerException
的可用性。”
JEP 358的“动机”部分包括以下段落:“如果JVM可以提供查明NPE来源并确定其根本原因所需的信息,而无需使用额外的工具或改组代码,则整个Java生态系统将受益。 自2006年以来,SAP的商业JVM就已经做到了这一点,获得了开发人员和支持工程师的一致好评。”
社区对OpenJDK的贡献示例
我感兴趣的JEP 358的一方面是它的背景。 JEP 358的“测试”部分当前指出:“自2006年以来,SAP的商业JVM中就已经实现了先前的实现,并且已经证明是稳定的。” 该声明的目的是证明已经对该功能进行了一些测试,但同时指出, SAP及其人员是提出的JDK增强功能的主要贡献者。 JEP的作者Goetz Lindenmaier和Ralf Schmelter ( 被视为原始作者 )已经或已经与SAP保持联系。 我的理解是, SAP OpenJDK版本 ( SapMachine )尚不包含此功能,但商业SAP却包含。 提议的JDK增强功能是一个很好的例子,说明多个供应商提供OpenJDK的实现如何在将来使每个人都受益于OpenJDK。
更多细节的缺点
JEP 358解决了由更详细的NPE引入的潜在安全风险。 它指出:“ null-detail消息可能包含源代码中的变量名……如果调试信息包含在类文件( javac -g
)中”,并且“这些以前尚未通过Java的反射API提供给其他程序。”
启用详细的空消息
JEP 358的“替代方案”部分概述了三个人们可能不希望使用较新的更详细的NPE消息的原因(性能,安全性和兼容性)。 它指出:“ null
-detail消息默认情况下处于关闭状态,可以通过命令行选项-XX:+SuppressCodeDetailsInExceptionMessages
启用。” 该部分补充说:“没有办法指定仅关注某些NPE提升字节码”(换句话说,这是一个全有或全无的选择)。 本节以以下语句结束:“我们打算在将来的版本中默认启用null详细信息。”
并非所有NullPointerException
更详细的消息
JEP 358指出了将应用更详细的消息的NullPointerException
类型,并将其与将不应用更详细的消息的类型进行了对比。 它指出(我特别强调 ),“ 只有由JVM直接创建和抛出的NPE才会包含null-detail消息。 由JVM上运行的程序显式创建和/或显式抛出的NPE不受以下字节码分析和空细节消息创建的约束。 另外,没有报告由隐藏方法中的代码引起的NPE的空细节消息,这些方法是由JVM生成和调用的专用低级方法,例如用于优化字符串连接。 隐藏的方法没有文件名或行号,可以帮助查明NPE的来源,因此打印空详细信息将是徒劳的。 如文本所述,没有理由尝试提供“隐藏方法”的详细信息。 对于我们自己的代码明确抛出的NPE,我们能够在构造异常消息时为其添加有用的上下文。
结论
对此JEP的响应非常热情,我认为有很多Java开发人员都希望在以后的OpenJDK发行版中提供更详细的NullPointerException
消息。 JDK-8218628 (“向NullPointerException添加详细消息,描述什么为null。”)与JEP 358 ( JDK-8220715 )关联,当前与JDK 14关联为“修复版本”。 希望JEP 358正式针对JDK 14!
翻译自: https://www.javacodegeeks.com/2019/08/jep-358-helpful-nullpointerexceptions.html