Java 空参数的 IllegalArgumentException 或 NullPointerException?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3881/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 23:31:33  来源:igfitidea点击:

IllegalArgumentException or NullPointerException for a null parameter?

javaexceptionnullnullpointerexceptionillegalargumentexception

提问by Mike Stone

I have a simple setter method for a property and nullis not appropriate for this particular property. I have always been torn in this situation: should I throw an IllegalArgumentException, or a NullPointerException? From the javadocs, both seem appropriate. Is there some kind of an understood standard? Or is this just one of those things that you should do whatever you prefer and both are really correct?

我有一个简单的属性设置方法,null不适合这个特定的属性。在这种情况下我一直很纠结:我应该扔一个IllegalArgumentException,还是一个NullPointerException?从 javadocs 来看,两者似乎都很合适。是否有某种可以理解的标准?或者这只是你应该做任何你喜欢做的事情之一,而且两者都是正确的?

采纳答案by Greg Hurlman

It seems like an IllegalArgumentExceptionis called for if you don't want nullto be an allowed value, and the NullPointerExceptionwould be thrown if you were trying to usea variable that turns out to be null.

IllegalArgumentException如果您不想null成为允许的值,似乎需要调用an ,NullPointerException如果您尝试使用结果为null.

回答by Jeremy Privett

If it's a settermethod and nullis being passed to it, I think it would make more sense to throw an IllegalArgumentException. A NullPointerExceptionseems to make more sense in the case where you're attempting to actually use the null.

如果它是一个setter方法并且null正在传递给它,我认为抛出一个IllegalArgumentException. 一个NullPointerException似乎更有意义,在你试图实际使用的情况null

So, if you're using it and it's null, NullPointer. If it's being passed in and it's null, IllegalArgument.

因此,如果您正在使用它并且它是null, NullPointer. 如果它被传入并且它是null, IllegalArgument

回答by Mark Renouf

I tend to follow the design of JDK libraries, especially Collections and Concurrency (Joshua Bloch, Doug Lea, those guys know how to design solid APIs). Anyway, many APIs in the JDK pro-actively throws NullPointerException.

我倾向于遵循 JDK 库的设计,尤其是集合和并发(Joshua Bloch、Doug Lea,那些人知道如何设计可靠的 API)。无论如何,JDK 中的许多 API 都会主动抛出NullPointerException.

For example, the Javadoc for Map.containsKeystates:

例如,JavadocMap.containsKey声明:

@throws NullPointerException if the key is null and this map does not permit null keys (optional).

如果键为空并且此映射不允许空键(可选),则@throws NullPointerException。

It's perfectly valid to throw your own NPE. The convention is to include the parameter name which was null in the message of the exception.

抛出你自己的 NPE 是完全有效的。约定是在异常消息中包含为空的参数名称。

The pattern goes:

模式如下:

public void someMethod(Object mustNotBeNull) {  
    if (mustNotBeNull == null) {  
        throw new NullPointerException("mustNotBeNull must not be null");  
    }  
}

Whatever you do, don't allow a bad value to get set and throw an exception later when other code attempts to use it. That makes debugging a nightmare. You should always the follow the "fail-fast" principle.

无论您做什么,都不允许设置错误的值并在以后其他代码尝试使用它时抛出异常。这使得调试成为一场噩梦。您应该始终遵循“快速失败”原则。

回答by jassuncao

If you choose to throw a NPE and you are using the argument in your method, it might be redundant and expensive to explicitly check for a null. I think the VM already does that for you.

如果您选择抛出 NPE 并且在您的方法中使用该参数,则显式检查 null 可能是多余且昂贵的。我认为 VM 已经为您做到了。

回答by Claude Houle

The accepted practice if to use the IllegalArgumentException( String message )to declare a parameter to be invalid and give as much detail as possible... So to say that a parameters was found to be null while exception non-null, you would do something like this:

如果使用IllegalArgumentException( String message )来声明参数无效并提供尽可能多的详细信息,那么可接受的做法是说发现参数为空而异常非空,你会做一些事情像这样:

if( variable == null )
    throw new IllegalArgumentException("The object 'variable' cannot be null");

You have virtually no reason to implicitly use the "NullPointerException". The NullPointerException is an exception thrown by the Java Virtual Machine when you try to execute code on null reference (Like toString()).

您几乎没有理由隐式使用“NullPointerException”。NullPointerException 是 Java 虚拟机在您尝试对空引用执行代码时抛出的异常(如toString())。

回答by GaryF

The standard is to throw the NullPointerException. The generally infallible "Effective Java" discusses this briefly in Item 42 (first edition), Item 60 (second edition), or Item 72 (third edition) "Favor the use of standard exceptions":

标准是扔NullPointerException. 通常不会出错的“Effective Java”在第 42 条(第一版)、第 60 条(第二版)或第 72 条(第三版)“支持使用标准异常”中对此进行了简要讨论:

"Arguably, all erroneous method invocations boil down to an illegal argument or illegal state, but other exceptions are standardly used for certain kinds of illegal arguments and states. If a caller passes null in some parameter for which null values are prohibited, convention dictates that NullPointerException be thrown rather than IllegalArgumentException."

“可以说,所有错误的方法调用都归结为非法参数或非法状态,但其他异常通常用于某些类型的非法参数和状态。如果调用者在某些禁止空值的参数中传递 null,则约定规定抛出 NullPointerException 而不是 IllegalArgumentException。”

回答by martinatime

The definitions from the links to the two exceptions above are IllegalArgumentException: Thrown to indicate that a method has been passed an illegal or inappropriate argument. NullPointerException: Thrown when an application attempts to use null in a case where an object is required.

指向上述两个异常的链接的定义是 IllegalArgumentException:抛出以指示方法已传递非法或不适当的参数。NullPointerException:当应用程序在需要对象的情况下尝试使用 null 时抛出。

The big difference here is the IllegalArgumentException is supposed to be used when checking that an argument to a method is valid. NullPointerException is supposed to be used whenever an object being "used" when it is null.

这里的最大区别是在检查方法的参数是否有效时应该使用 IllegalArgumentException。NullPointerException 应该在对象为 null 时“使用”时使用。

I hope that helps put the two in perspective.

我希望这有助于正确看待两者。

回答by Allain Lalonde

Couldn't agree more with what's being said. Fail early, fail fast. Pretty good Exception mantra.

不能更同意所说的话。早点失败,快点失败。非常好的例外咒语。

The question about which Exception to throw is mostly a matter of personal taste. In my mind IllegalArgumentException seems more specific than using a NPE since it's telling me that the problem was with an argument I passed to the method and not with a value that may have been generated while performing the method.

关于抛出哪个异常的问题主要是个人品味的问题。在我看来,IllegalArgumentException 似乎比使用 NPE 更具体,因为它告诉我问题在于我传递给方法的参数,而不是执行方法时可能生成的值。

My 2 Cents

我的 2 美分

回答by erickson

If it's a "setter", or somewhere I'm getting a member to use later, I tend to use IllegalArgumentException.

如果它是一个“setter”,或者我在某个地方让成员稍后使用,我倾向于使用 IllegalArgumentException。

If it's something I'm going to use (dereference) right now in the method, I throw a NullPointerException proactively. I like this better than letting the runtime do it, because I can provide a helpful message (seems like the runtime could do this too, but that's a rant for another day).

如果这是我现在要在方法中使用(取消引用)的东西,我会主动抛出 NullPointerException。我更喜欢这个而不是让运行时去做,因为我可以提供一个有用的消息(似乎运行时也可以这样做,但这是另一天的咆哮)。

If I'm overriding a method, I use whatever the overridden method uses.

如果我要覆盖一个方法,我会使用被覆盖的方法所使用的任何东西。

回答by erickson

In general, a developer should neverthrow a NullPointerException. This exception is thrown by the runtime when code attempts to dereference a variable who's value is null. Therefore, if your method wants to explicitly disallow null, as opposed to just happening to have a null value raise a NullPointerException, you should throw an IllegalArgumentException.

通常,开发人员永远不应该抛出 NullPointerException。当代码尝试取消引用值为 null 的变量时,运行时会抛出此异常。因此,如果您的方法想要明确禁止 null,而不是恰好让 null 值引发 NullPointerException,则您应该抛出 IllegalArgumentException。