Should I throw a NullPointerException explicitly or let Java do it for me?
正如标题所说,我想知道关于抛出nullpointerExceptions的最佳实践是什么。具体来说,如果我有一个外部库函数,可以在我不想实际处理的情况下返回
第一种方法允许我添加一些额外的信息,因为我可以构造NullPointerException,但是第二种方法在我看来可以使代码更干净。我也想知道任何性能的影响,也就是说,Java更有效地投掷NPE"原生"?
举个例子,我尝试使用Java语音API来创建一个语音合成器,使用以下代码:
1 2 3 4 5 6 7 8 9 | synthesizer = Central.createSynthesizer(generalDesc); if (synthesizer == null) { // (1) throw NPE explicitly throw new NullPointerException("No general domain synthesizer found."); } // (2) let the JVM throw the NPE when dereferencing synthesizer.allocate(); |
如果找不到合适的合成器,
附录:考虑当JVM启动需要在文件系统上(通常)"用户.home"或"java.home /LIB"中加载时,令人困惑的是,EDCOX1 OR 6不直接抛出NPE(这是我最初在弗洛伊德滑动中写的),但是它返回NULL,而不是返回NULL。.I认为抛出NullPointerException是正确的操作,因为它指示软件部署中的实际错误。
在你的情况下:两者都没有。检查
一般来说,如果NPE不应该发生,不要明确地测试它,Java会为你做。编写的测试更少,读取的代码更少,分析的复杂性更低。
但是,如果预计
我想说的是,您不应该显式地创建
我不喜欢空值是一个有效的返回值,即使在"特殊情况"下也是如此。所以我采取了另一种方法。
在您的例子中,我将用@notnull(@notnull是一个令人惊奇的注释)注释方法createSynthester(…)。当CreateSynthester(…)想要返回空值时,我将得到一个非法状态异常,而不是NPE。
你会得到A:
1 | java.lang.IllegalStateException: @NotNull method .../.../createSynthetiser(...) must not return null |
这种方法有几个好处:
NullPointerException和IllegalstateException都扩展了RuntimeException,因此您不会从根本上更改程序。
如果发生错误,应立即抛出异常(不迟于以后,当您检查/抛出自己或尝试取消引用空值时)
你不必费心写如果…==空/抛出部分。
作为一个,巨大的,额外的好处,一些IDE(如intellij-ide a)将实时警告您可能的@notnull违规行为。
关于原始代码:
1 2 3 4 5 6 7 8 9 | synthesizer = Central.createSynthesizer(generalDesc); if (synthesizer == null) { // (1) throw NPE explicitly throw new NullPointerException("No general domain synthesizer found."); } // (2) let the JVM throw the NPE when dereferencing synthesizer.allocate(); |
我的看法是,像这里所显示的那样抛出NPE是可以的,但有巨大的警告。只有当npe-ctor参数是一个足够描述性的(并且希望是唯一的)消息(希望从常量或资源集中提取一个)时,才需要注意这个问题。另一个需要注意的是,您的主要优先权是把事情弄出去,这样的情况a,这将被视为一个可接受的快速n脏解决方案。
在理想情况下,我的偏好是使用特定于无效配置的异常。当它们不可用时,可以使用NPE子类(如Apache Commons Math的NullArgumentException)或Apache Common Lang 2.x中的旧异常。这是我对NPE和IllegalArgument类型异常的立场。我不一定同意ApacheCommonalLang在使用标准JDK异常而不是更语义相关的异常方面的立场。但那只是我,我正在偏离正切…
…所以回到最初的问题。正如我之前所说,以一种快速的N-肮脏的方式扔下这样的NPE是可以的(当你在其中一个"需要得到的SH1T出来!"!(10+1)"各种情况。
但是请注意,这是由应用程序或系统配置问题引起的NPE,因为您正确地识别了它。也就是说,NPE不是由另一个错误条件(在本例中是配置或环境错误)的症状或影响造成的根本原因。
Central.createSynthesizer returns null if it cannot find a suitable
synthesizer, which is most often caused by a missing speech.properties
file. So it's a matter of wrong setup of the system, and pretty
unrecoverable from at runtime, rather than circumstances that need to
be handled programmatically.
不可恢复性不是确定的。应用程序可以有其他方法以编程方式处理这种情况。
As such, I believe throwing a
NullPointerException is a valid response, since it indicates a bug
(not in the code but in the deployment of the software). But since the
synthesizer object is dereferenced in the very next statement, should
I just let the JVM throw the NPE for me and save the null check?
我不会这么做的,即使是在这样的情况下。由JVM以这种方式抛出的NPE将在其中包含一个非常不具格式性的消息。通常,检查所有内容是否为空,并在遇到描述性异常时抛出一个异常(NPE或其他异常)。
如果你能保证你得到的任何东西(例如参数)已经被检查过了,不要检查NPE(以合同方式设计)。
Addendum: Considering that speech.properties gets loaded when the JVM
starts needs to exist on the filesystem in (normally)"user.home" or
"java.home/lib", it is puzzling that createSynthesizer doesn't
straight up throw an NPE (which is what I had written originally in a
Freudian slip) when it fails to find it but returns null instead.
同样,这是因为对这种情况的响应是特定于应用程序的。应用程序可能会决定采用部分功能的跛行模式,而不是崩溃和燃烧到地面。如果
I think that throwing a NullPointerException is the right thing to do
here, because it indicates an actual bug in the deployment of the
software.
再说一次,只有当NPE是一个快速的N-肮脏的解决方案,才能把事情弄出去。在这种情况下,一切正常。更好的方法是识别这是什么,配置错误。
因此,最好具有特定于应用程序的异常,如IllegalConfigurationException或InvalidConfigurationException或IncompleteConfigurationException。我不喜欢在这种情况下使用
我从未使用过Java,但是如果我正在使用该应用程序,我希望看到一个错误消息而不是崩溃。对我来说,nullpointerException听起来像是代码中的一个bug——我宁愿看到一条错误消息,其中包含如何正确配置程序的说明,或者至少是指向具有此类说明的网页的超链接。
如果我是一个用户,看到一个程序以nullpointerException终止,我会针对该程序提交一个bug,或者至少对下一步该做什么感到困惑。
很有趣的问题。
我认为该方法应该抛出某种类型的
我会进行空检查并抛出一个NPE或您自己的其他自定义