Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我应该显式抛出NullPointerException还是让Java来为我做?_Java_Null_Nullpointerexception - Fatal编程技术网

我应该显式抛出NullPointerException还是让Java来为我做?

我应该显式抛出NullPointerException还是让Java来为我做?,java,null,nullpointerexception,Java,Null,Nullpointerexception,正如标题所说,我想知道关于抛出NullPointerException的最佳实践是什么。具体地说,如果我有一个外部库函数,它可以在我不想实际处理的情况下返回null(参见下面的特定示例),因为null表示软件有问题。问题是,我应该吗 检查null的返回值并自己抛出NullPointerException,或者 当我尝试使用对象时,我是否应该让Java为我做一些肮脏的工作 第一种方法允许我添加一些额外的信息,因为我可以构造NullPointerException,但在我看来,第二种方法有助于更干净

正如标题所说,我想知道关于抛出NullPointerException的最佳实践是什么。具体地说,如果我有一个外部库函数,它可以在我不想实际处理的情况下返回
null
(参见下面的特定示例),因为
null
表示软件有问题。问题是,我应该吗

  • 检查
    null
    的返回值并自己抛出NullPointerException,或者
  • 当我尝试使用对象时,我是否应该让Java为我做一些肮脏的工作
  • 第一种方法允许我添加一些额外的信息,因为我可以构造NullPointerException,但在我看来,第二种方法有助于更干净的代码。我还想知道任何性能影响,也就是说,Java在“本地”抛出NPE方面是否更有效

    作为示例,我尝试使用Java语音API创建一个语音合成器,使用以下代码:

    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();
    

    Central.createSynthesizer
    如果找不到合适的合成器,则返回
    null
    ,这通常是由于缺少speech.properties文件造成的。因此,这是一个系统设置错误的问题,并且在运行时是不可恢复的,而不是需要以编程方式处理的情况。因此,我认为抛出NullPointerException是一个有效的响应,因为它表示一个bug(不是在代码中,而是在软件的部署中)。但是由于
    合成器
    对象在下一条语句中被取消引用,我是否应该让JVM为我抛出NPE并保存空检查


    附录:考虑到JVM启动时加载speech.properties需要存在于文件系统中(通常为“user.home”或“java.home/lib”),让人费解的是
    createSynthesizer
    没有直接抛出NPE(这是我最初在弗洛伊德纸条中写的)当它找不到它但返回null时。我认为在这里抛出NullPointerException是正确的做法,因为它表明软件部署中存在实际缺陷。

    我想说的是,您永远不应该显式创建
    NullPointerException
    ,而应该使用更清楚地描述情况的异常类型。在您的情况下,我认为
    IllegalStateException
    适合“系统设置错误,在运行时无法恢复”的情况。或者您可以创建自己的
    组件missingexception
    。在所需方法参数为
    null
    的情况下,通常使用
    IllegalArgumentException

    在您的情况下:两者都不使用。检查
    null
    并抛出更有意义的异常,而不是NPE

    一般来说,如果NPE不应该出现,不要显式地测试它,Java会为您做的。编写的测试更少,读取的代码更少,分析的复杂性也更少

    但是,如果预计
    null
    ,则应尽快测试并进行相应解释。否则,
    NullPointerException
    将在稍后的某个地方以不同的行/方法出现,这使得调试真正的问题变得更加困难。

    我不喜欢让null成为有效的返回值,即使在“异常情况”下也是如此。因此,我采取了另一种方法

    在你的例子中,我会用@NotNull(@NotNull是一个惊人的注释)注释方法createSynthesizer(…)。当createSynthesizer(…)想要返回null时,我会得到一个非法状态异常,而不是NPE

    你会得到一个:

    java.lang.IllegalStateException: @NotNull method .../.../createSynthetiser(...) must not return null
    
    这种方法有几个好处:

    • NullPointerException和IllegalStateException都扩展了RuntimeException,所以您不会从根本上更改程序

    • 发生错误时,应立即抛出异常(而不是稍后,在您检查/抛出自己或尝试取消引用null时)

    • 您无需费心编写if…==空/抛出部分


    作为一个巨大的额外好处,一些IDE(如IntelliJ IDEA)将实时警告您可能发生的@NotNull违规行为。

    非常有趣的问题

    我认为该方法应该抛出某种类型的
    问题CreatingSynthesizerException
    ,而不是返回null


    我会进行空检查,并抛出一个NPE或其他自定义
    问题以及您自己的SynthesizeRexception
    (出于某种原因,Sun将此异常视为JVM ish异常,不打算供程序员使用。这是一些认证教程和书籍中所说的。但是,我不相信这一点,有些人经常将自己的NPE放入我的库中)。

    关于原始代码:

    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参数是一个足够描述性(并且希望是唯一的)消息(希望是从常量或资源集中提取的)时,才可以这样做另一个警告是,你的首要任务是把东西搬出去,在这种情况下,这算是一个可以接受的快速解决方案

    在理想情况下,我的首选是使用特定于无效配置的异常。当这些异常不可用时,可以使用NPE子类(如Apache Commons Math)或者是在中发现的旧异常。这是我对NPE和IllegalArgument类型异常的立场。我不一定同意Apache Common Lang关于更喜欢使用标准JDK异常而不是语义相关的异常的观点。但这只是我,我正在脱离正切

    …那么回到原来的问题。正如我之前所说的,像这样快速地抛出NPE是可以的(当你处于那种“需要把那个sh1t弄出来!!(10+1)”的情况下)

    然而,请注意,这