有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java捕获和抛出nullpointerexception的最佳实践?

捕捉nullpointerexception似乎不是一个好主意。如果是这样的话,为什么要用方法抛出呢?它应该只是被捕捉到例外吗

此外,如果我遇到一个空参数(可以是字符串之类的基本类型,也可以是带有字段的类),我应该如何处理它?(假设没有扔npe)

谢谢


共 (3) 个答案

  1. # 1 楼答案

    它是一个运行时异常,因此不会深入到程序代码中,只会被JVM捕获在顶层(或接近顶层)或[/update]。由于运行时异常表明存在严重问题(通常是严重的编程错误、配置/集成问题等),因此最好让它们传播到顶层,这通常会导致整个线程异常失败。这发出了一个强烈的信号,表明有问题,需要尽快解决

    另见Is Catching a Null Pointer Exception a Code Smell?

    Also, if I encounter a parameter which is null [...], how should I handle it?

    一般来说,投掷NPE是可以的。但是,根据情况,您也可以考虑^{}using an assertion。另见

  2. # 2 楼答案

    在最有可能的情况下,您可能希望捕获NPE是在您正在实现一种框架时,也就是说,您不想终止应用程序,而是报告错误,并且您有一种(明智地)继续应用程序的方法

  3. # 3 楼答案

    这个答案可能很长,但我认为值得

    It seems like it is not a good idea to catch a nullpointerexception.

    你是对的,你不应该捕捉NullPointerException,也不应该捕捉任何运行时异常

    If that's the case, why is it thrown by methods? Should it just be caught with Exception?

    它用于指示发现编程错误。这些编程错误可以而且应该用代码修复(也就是说,它们是可以预防的)

    Also, if I encounter a parameter which is null how should I handle it? [...](assumingly not throw npe)?

    这取决于你想用它做什么。对于某些逻辑,可能允许使用null值。如果是这种情况,则验证null的存在并对其进行处理,要么提供默认值,要么避免向null发送消息

    比如说。假设你有一个账单信息系统,你有这个代码保存客户信息,你可以选择保存客户额外信息

    在这种情况下,可选消息可能为null,您的代码应该验证它的存在

    例如:

    /**
    * ...
    * @param - OptionalMessage may be null, include anything else you wan to save.
    */
    public void sendCustomerInformation( Customer c , OptionalMessage optionalMessage ) { 
       SomeMessage message = SomeMessage.createMessage();
       message.setHeader( c.name() );
       message.setCustomerInformation( c );
       if( optionalMessage != null ) { // is optional? handle it
          message.add( optionalMessage.status() );
          message.add( optionalMessage.summary() );
          message.add( optionalMessage.message() );
        }
     }
    

    }

    验证null的存在并记录它

    但同样的代码也有一个客户作为参数,在这种情况下,您可以:

    什么都不做 b)也验证它 c)根据该级别的抽象级别抛出不同的异常

    例如,上面的代码没有任何作用。这将导致调用代码c.name()的NullPointerException,这应该在开发测试的早期捕获。此外,它还应该记录在参数和javadoc中的抛出中

    /**
     * ...
     * @param  c - The customer whose information is to be sent. NotNull 
     * ...
     * @throws NullPointerException if the customer is null
     */
    public void sendCustomerInformation( Customer c , OptionalMessage optionalMessage ) { 
       SomeMessage message = SomeMessage.createMessage();
       ...
    

    如果有人使用null调用此方法,Npe将指示他们编码错误。另外,Npe将非常快速地说出编码错误是什么以及在哪里(当使用null customer调用sendCustomerInformation

    选项b)验证它。可能是这样的,当您可以允许处理空客户时(这没有意义,但这是一个选项)

    在这种情况下,您可能会验证它并提前返回(以我已完成的方式)

    public void sendCustomerInformation( Customer c , OptionalMessage optionalMessage ) { 
       if( cusomer == null ) {  return; // I'm done! } 
       // else 
       SomeMessage message = ... 
       ..
    }
    

    或者可以创建一个替换:

    public void sendCustomerInformation( Customer c , OptionalMessage optionalMessage ) { 
       if( cusomer == null ) {  c = new EmptyCustomer() ;} 
       // else 
       SomeMessage message = ... 
       ..
    }
    

    选项c)这与a类似,但在本例中,根据抽象级别抛出异常。例如,如果这将在GUI或其他东西中显示给最终用户,只抛出Npe可能没有意义:

    public void sendCustomerInformation( Customer c , OptionalMessage optionalMessage ) { 
       if( cusomer == null ) {  
         // oh oh  something went wrong. 
         log.fatal("Invalid argument on \"sendCustomerInformation\" );
         throw new MyApplicationException("Dear customer, the information yada yaa"); 
       } 
       ...
    

    如果这是应用程序中的某种无效状态:

    public void sendCustomerInformation( Customer c , OptionalMessage optionalMessage ) { 
       if( cusomer == null ) {  
         // wait a minute, how could... why did.. what?
         throw new IllegalStateException("Hey, I got null on sendCustomerInformation and this shouldn't happen");
       }
       ...
    

    因为可能应用程序负责将该对象/参数保持在有效形状

    结论

    所以这取决于场景,但一般来说,NullPointerException(以及大多数RuntimeException)表示可以用代码修复的东西(这是程序员的错误),并且您可以随时对此采取措施。有些情况下,你对此无能为力,你能做的最好的事情就是让它爆发

    我希望这有帮助

    另见:Exception other than RuntimeException