Java 以编程方式抛出 NullPointerException 是否可以?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3322638/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it okay to throw NullPointerException programmatically?
提问by stratwine
When there is a post-condition, that return value of a method must not be null, what can be done?
当有后置条件时,方法的返回值不能为空,怎么办?
I could do
我可以
assert returnValue != null : "Not acceptable null value";
but assertions could be turned off!
但是断言可以关闭!
So is it okay to do
那么可以吗
if(returnValue==null)
{
throw new NullPointerException("return value is null at method AAA");
}
?
?
Or is it better to use a user-defined exception (like NullReturnValueException ) for such a condition?
还是在这种情况下使用用户定义的异常(如 NullReturnValueException )更好?
采纳答案by waxwing
I see no problem with throwing a NPE as early as possible before the JVM does it for you - in particular for null arguments. There seems to be some debate about this, but there are many examples in the Java SE libraries that does exactly this. I cannot see why NPE should be holy in the aspect that you are not able to throw it yourself.
我认为在 JVM 为您执行之前尽早抛出 NPE 没有问题 - 特别是对于空参数。似乎对此存在一些争论,但 Java SE 库中有许多示例正是这样做的。我不明白为什么 NPE 在你不能自己扔的方面应该是神圣的。
However, I digress. This question is about something different. You are talking about a post-condition stating that the return value mustn't be null. Surely null in this case would mean you have a bug inside the very method?
不过,我离题了。这个问题是关于不同的东西。您正在谈论一个后置条件,说明返回值不能为空。在这种情况下肯定 null 意味着您在非常方法中存在错误?
How would you even document this? "This method throws a NullPointerException if the return value unexpectedly is null"? Without explaining how this could happen? No, I would use an assertion here. Exceptions should be used for errors that can conceivably happen - not to cover things that can happen if there's something wrong inside the method, because that does not help anybody.
你会如何记录这个?“如果返回值意外为空,此方法会抛出 NullPointerException”?没有解释这怎么会发生?不,我会在这里使用断言。异常应该用于可能发生的错误 - 不要涵盖如果方法内部有问题可能发生的事情,因为这对任何人都没有帮助。
回答by Timo Geusch
Given that NullPointerException
is the idiomatic way to communicate an unexpected null value in Java, I would recommend you throw a standard NullPointerException
and not a homegrown one. Also keep in mind that the principle of least surprise would suggest that you don't invent your own exception type for a case where a system exception type exists.
鉴于这NullPointerException
是在 Java 中传达意外空值的惯用方式,我建议您抛出标准NullPointerException
而不是自产的标准。还要记住,最小意外原则建议您不要为存在系统异常类型的情况发明自己的异常类型。
Assertions are good for debugging but not good if you have to handle certain conditions so that's not really a good way to handle the error condition.
断言对调试很有用,但如果您必须处理某些情况,则不好,因此这不是处理错误情况的真正好方法。
回答by Rafe Kettler
A book I have called O'Reilly's Java in A Nutshellwhich is written by an expert lists this definition for NullPointerException:
一本我称之为O'Reilly's Java in A Nutshell 的书是由一位专家写的,它列出了 NullPointerException 的这个定义:
Signals an attempt to access a field or invoke a method of a null object.
表示尝试访问字段或调用空对象的方法。
Since returning null isn't either of those things, I think it'd be more appropriate to write your own exception.
由于返回 null 不是这些事情中的任何一个,我认为编写自己的异常更合适。
回答by meriton
The JavaDoc for NullPointerExceptionstates:
NullPointerException的JavaDoc指出:
Thrown when an application attempts to use null in a case where an object is required. These include:
* Calling the instance method of a null object. * Accessing or modifying the field of a null object. * Taking the length of null as if it were an array. * Accessing or modifying the slots of null as if it were an array. * Throwing null as if it were a Throwable value.
Applications should throw instances of this class to indicate other illegal uses of the null object.
当应用程序在需要对象的情况下尝试使用 null 时抛出。这些包括:
* Calling the instance method of a null object. * Accessing or modifying the field of a null object. * Taking the length of null as if it were an array. * Accessing or modifying the slots of null as if it were an array. * Throwing null as if it were a Throwable value.
应用程序应抛出此类的实例以指示 null 对象的其他非法使用。
I consider violating the post-condition an illegal action. However, I think what exception you use doesn't matter much, because we are talking about a code path that should be (and hopefully is) unreachable, and hence you will not have error handling specific to that exception, and hence the only effect of that name is a different wording of some entry in a log file nobody is ever likely to see.
我认为违反后置条件是非法行为。但是,我认为您使用什么异常并不重要,因为我们正在讨论一个应该(并且希望是)无法访问的代码路径,因此您不会有特定于该异常的错误处理,因此唯一的影响该名称是日志文件中某个条目的不同措辞,没有人可能会看到。
If in contrast you think the post condition is likely to be violated it might be a good idea to include more debugging information, such as the arguments the method was invoked with.
相反,如果您认为可能违反了后置条件,则最好包含更多调试信息,例如调用方法的参数。
回答by Affe
There certainly isn't a universal law against throwing NullPointerException, but it's tough to answer if you actually should in such an abstracted example. What you don't want to do is put people up the chain in the position of trying to catch NullPointerException. Code like this (real example, I swear):
当然没有反对抛出 NullPointerException 的普遍规律,但在这样一个抽象的例子中,如果你真的应该这样做,很难回答。您不想做的是将人们置于试图捕获 NullPointerException 的位置。像这样的代码(真实的例子,我发誓):
catch (NullPointerException npe) {
if (npe.getMessage().equals("Null return value from getProdByCode") {
drawToUser("Unable to find a product for the product type code you entered");
}
}
Is a surefire indicator you're doing something wrong. So if the null return value is an indicator of some system state that you're actually able to communicate, use an exception that communicates that state. There aren't many cases I can think of where it makes sense to null check a reference just to chuck a nullpointer. Usually the very next line of code would have chucked the nullpointer (or something more informative) anyway!
是一个万无一失的指标,你做错了什么。因此,如果 null 返回值是您实际能够进行通信的某个系统状态的指示符,请使用传达该状态的异常。我能想到的情况并不多,因为空检查引用只是为了夹一个空指针是有意义的。通常,下一行代码无论如何都会丢弃空指针(或更多信息)!
回答by Thorbj?rn Ravn Andersen
I would consider that usage of NullPointerException ok, ifyou remember the description. That is what the person investigating has work with (line numbers may shift). Also remember to document that your methods throw null pointer exceptions in special cases.
如果您还记得描述,我会认为 NullPointerException 的用法没问题。这就是调查人员的工作(行号可能会发生变化)。还要记住记录您的方法在特殊情况下会抛出空指针异常。
If you check your method parameters right in the beginning, a throw new IllegalArgumentException("foo==null")
is acceptable to me too.
如果你一开始就检查你的方法参数,throw new IllegalArgumentException("foo==null")
我也可以接受。
回答by Roman
I would recommend you never throw NullPointerException
by yourself.
我建议你永远不要NullPointerException
自己扔。
The main reason not to do this, as Thorbj?rn Ravn Andersen says in a comment below, is that you don't wan't to mix 'real, bad NPEs' with NPEs thrown intentionally.
不这样做的主要原因,正如 Thorbj?rn Ravn Andersen 在下面的评论中所说,是你不想将“真正的、糟糕的 NPE”与故意抛出的 NPE 混合在一起。
So, until you're confident that you're able to recognize 'valid' NPE, I'd recommend to use IllegalArgumentException
when you want to tell to your API user that null
is not a valid argument value. Your method's behavior when illegal null-parameter passed should be documented.
因此,在您确信自己能够识别“有效”NPE 之前,我建议IllegalArgumentException
您在想告诉 API 用户这null
不是有效参数值时使用。应该记录传递非法空参数时您的方法的行为。
Another (more modern imho) option is to use @NotNull
annotation near the argument.
Here is an article about using @NotNull annotation.
另一个(更现代的恕我直言)选项是@NotNull
在参数附近使用注释。这是一篇关于使用 @NotNull 注释的文章。
As I mentioned earlier, there can also be cases, when throwing NPE will not be confusing either to you or to your teammates: NPE cause should be clear and recognizable.
正如我之前提到的,也有可能出现这样的情况,即投掷 NPE 不会让您或您的队友感到困惑:NPE 的原因应该是明确且可识别的。
For instance, if you use some library with preconditions module, like Guava
, then I find using checkNotNull()
-like methods is a preferable way to deal with illegally-passed nulls.
例如,如果你使用一些带有前置条件模块的库,比如Guava
,那么我发现使用checkNotNull()
-like 方法是处理非法传递的空值的更好方法。
checkNotNull(arg, msg)
throws NPE, but from the stacktrace it's quite clear, that it was produced by Preconditions.checkNotNull()
and thus it's not an unknown bug but rather expected behavior.
checkNotNull(arg, msg)
抛出 NPE,但从堆栈跟踪中很清楚,它是由产生的Preconditions.checkNotNull()
,因此它不是一个未知的错误,而是预期的行为。
回答by Jerod Houghtelling
IMO you should never manually throw a NullPointerException. The calling routine wouldn't know if the real or manual NullPointerException without checking the description. In this case it looks like you would want to roll your own exception that matches the problem closer, so that the calling method can correctly recover frm this exception. Maybe a PostConditionException would be generic enough for many circumstances.
IMO 你永远不应该手动抛出 NullPointerException。如果不检查描述,调用例程将不知道是真实的还是手动的 NullPointerException。在这种情况下,您似乎希望滚动与问题更接近的自己的异常,以便调用方法可以正确地恢复此异常。也许 PostConditionException 在许多情况下足够通用。
回答by Truong Ha
Throw that exception is not a good practice in some case and I wonder why when you already catch it with the if statement?
在某些情况下抛出该异常不是一个好习惯,我想知道为什么当您已经用 if 语句捕获它时?
if(returnValue==null)
如果(返回值==空)
回答by Tim Bender
If you describe a method contract where the return value can not be null
, then you had better make sure you don't return null
. But this isn't a NullPointerException at all. If the value you have to return is null
then clearly the caller has either given you bad arguments (IllegalArgumentException), you are not in a valid state (IllegalStateException), or some other much more meaningful exceptional condition has occurred other than NullPointerException (which usually indicates a programming error).
如果你描述了一个不能返回值的方法契约null
,那么你最好确保你不返回null
。但这根本不是 NullPointerException。如果您必须返回的值null
显然是调用者给了您错误的参数 ( IllegalArgumentException)、您未处于有效状态 ( IllegalStateException),或者发生了除 NullPointerException 之外的其他更有意义的异常情况(通常表示编程错误)。
回答by CurtainDog
In the Java-verse null is always a valid value when expecting an object. You're better off avoiding such impossible post conditions. If you really can't abide a null then you'll have to rework your method so you can return a primitive.
在 Java-verse 中,期望对象时 null 始终是有效值。你最好避免这种不可能的后期条件。如果你真的不能接受空值,那么你将不得不重新设计你的方法,这样你就可以返回一个原语。