Java 捕捉和抛出空点异常的最佳实践?
捕获nullpointerexception似乎不是一个好主意。如果是这样的话,为什么由方法抛出呢?它是否应该被异常捕获 另外,如果我遇到一个空参数(可以是字符串之类的基本类型,也可以是带有字段的类),我应该如何处理它?(假设没有投掷npe) 谢谢这是一个运行时异常,因此不希望深入到程序代码中,只希望JVM在顶层(或接近顶层)或[/update]。由于运行时异常表示严重的问题(通常是严重的编程错误、配置/集成问题等),因此最好让它们传播到顶层,这通常会导致整个线程异常失败。这发出了一个强烈的信号,表明有问题,需要尽快解决 另见 另外,如果我遇到一个null[…]的参数,我应该如何处理它 一般来说,投掷NPE是可以的。但是,根据情况,你也可以考虑,或者。另见Java 捕捉和抛出空点异常的最佳实践?,java,nullpointerexception,Java,Nullpointerexception,捕获nullpointerexception似乎不是一个好主意。如果是这样的话,为什么由方法抛出呢?它是否应该被异常捕获 另外,如果我遇到一个空参数(可以是字符串之类的基本类型,也可以是带有字段的类),我应该如何处理它?(假设没有投掷npe) 谢谢这是一个运行时异常,因此不希望深入到程序代码中,只希望JVM在顶层(或接近顶层)或[/update]。由于运行时异常表示严重的问题(通常是严重的编程错误、配置/集成问题等),因此最好让它们传播到顶层,这通常会导致整个线程异常失败。这发出了一个强烈的信号
NPE
和RuntimeException
通常在出现编码错误时抛出,这就是为什么捕获它们不是一个好主意。应该做的是修复无法处理空输入的代码
这是问题的第二部分,如何处理空输入。这完全取决于您在代码中合理期望的内容
假设您从数据库表中读取数据,并从可为空的列中读取空值,这绝对不是例外情况,因此您的代码应从业务角度(例如,忽略整行、提示用户输入值或仅使用伪值)将其视为适当的处理方法
但是,如果您正在从不可为null的列(例如主键)读取null值,则应该抛出特定于应用程序的异常,该异常(希望)由应用程序的UI处理
所以答案其实很简单:如果null是正常操作期间可能发生的值,那么相应地处理它,如果不是,则抛出一个已检查的业务异常,而不是一个
NPE
您可能希望捕获NPE的最有可能的情况是在您实现一种框架时,即,您不想终止应用程序,但要报告错误,您可以(明智地)继续应用程序。如果有人非法向您的方法传递Null,则抛出IllegalArgumentException而不是NP。这更好地描述了错误。nullpointerexception通常表示错误。如果您不希望出现这样的程序员错误,就不会捕获空指针异常。例如,假设您使用一个类型为P的参数实现了一个方法myMethod
void myMethod(P x)
假设您不希望参数x为null。在这种情况下,您可能不会检查null。为什么?因为您假设使用您的方法的程序员将正确地使用它,并且不会传递null。我不是说在这种情况下是否应该检查null。我只是想回答为什么有时候空指针异常是由一个方法抛出的,并且不应该被捕获。原因如下:您的方法可能会抛出null指针异常,因为有人没有正确使用它(传递null)。使用您的方法的程序员可能知道,如果该方法使用错误,它可能会抛出NullPointerException。但是,即使他错误地使用了您的方法,也不会捕获异常,因为每个人都认为该方法没有被误用
第二个问题:首先,字符串是一个对象,而不是一个基本类型。第二,原语不能为null(原语是int、double、float、chars、boolean等)。现在,如果您遇到一个null参数,并且它不应该为null(换句话说,您收到了一个非法参数),那么您有一些选择:
- 抛出一个指示参数为null且您的方法希望它不为null的
- 什么都不要做。假设您的方法使用正确(换句话说,假设没有程序员错误)
- 用法:
assert(x!=null)代码>
我个人不喜欢第二种选择,通常更喜欢第二种选择。但是,如果我想确保变量上有一些不变量,我还是使用断言。但是这些只是我的习惯,其他人可能不同意。为了避免代码中的空检查,在大多数情况下,返回空对象或空列表/映射/集而不是空值是合适的。这个答案可能很长,但我认为值得 捕获nullpointerexception似乎不是一个好主意 没错,您不应该捕获NullPointerException,也不应该捕获任何运行时异常 如果是这样的话,为什么由方法抛出呢?它是否应该被异常捕获 它用于指示发现编程错误。这些编程错误可以而且应该用代码修复(也就是说,它们是可以预防的) 另外,如果我遇到一个空参数,我应该如何处理它?[…](假设不抛出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的存在并记录它
但在本例中,同样的代码也有一个customer作为参数
/**
* ...
* @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();
...
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 = ...
..
}
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");
}
...