简体   繁体   English

检查方法参数是否为null?

[英]Check method parameter for null or not?

I have a method which doesn't allow null as parameter. 我有一个不允许将null作为参数的方法。 Should i check the parameter inside the method for null and throw a IllegalArgumentException? 我应该检查方法中的参数是否为null并抛出IllegalArgumentException吗? If yes, i would have to implement that check inside a lot of methods and it would look ugly. 如果是的话,我将不得不在很多方法中实施该检查,这看起来很难看。 So what is the best way? 那么最好的方法是什么?

Well, that's a question of personal preference. 好吧,这是个人喜好问题。 I'd say: Yes, you should. 我会说:是的,您应该。 It is a lot easier to debug if you throw an exception once you notice that there is a problem instead of getting an exception when you first access the object, maybe in an other method thousands of lines away. 如果一旦发现问题就抛出异常,而不是在首次访问对象时获取异常(可能是数千行以外的其他方法),则调试起来会容易得多。 (But throw a NullPointerException instead of IllegalArgumentException .) (但是抛出NullPointerException而不是IllegalArgumentException 。)

But you have to do this check manually. 但是您必须手动执行此检查。 Of course, you can write a helper method or use Guava's Preconditions : 当然,您可以编写辅助方法或使用Guava的Preconditions

public void test(final String string) {
    Preconditions.checkNotNull(string); // will throw a NullPointerException if string is null
}

Edit : Especially if you write an API to be used by others, it is helpful to tell the people whether you are expecting non-null values or whether null is okay. 编辑 :特别是如果您编写供其他人使用的API,告诉人们是期望非空值还是可以使用null会很有帮助。 You can do so using the @Nullable , @Nonnull (both per variable or field), @ParametersAreNonnullByDefault and @ParametersAreNullableByDefault annotations (both per class, package or method) located in javax.annotation (not part of the JDK). 您可以使用位于javax.annotation (不是JDK的一部分)中的@Nullable@Nonnull (每个变量或字段), @ParametersAreNonnullByDefault@ParametersAreNullableByDefault注释(每个类,包或方法)进行此操作。

Edit 2 : Okay, so why do I recommend to use a NPE instead of an IAE? 编辑2 :好的,为什么我建议使用NPE代替IAE? First of all, it's the standard way to handle this problem. 首先,这是处理此问题的标准方法。 The JDK does this, important libraries like Guava do this, and the one and only book about Java, Effective Java , recommends it (item 60). JDK做到了这一点,像Guava这样的重要库也做到了这一点,一本也是唯一一本有关Java的书, Effective Java ,推荐了它(项目60)。 But I know, this is not a valid argument. 但是我知道,这不是一个有效的论点。 In this answer mentioned by @fabian, @Jason Cohen argues in favor of a IAE. 在@fabian提到的这个答案中,@ Jason Cohen主张支持IAE。 His arguments are: 他的论据是:

  • Documentation/definition of the exceptions. 例外情况的文档/定义。 Yes, there is a list of applicable cases. 是的,这里有适用情况的清单。 But the JavaDoc also states that it is not overall. 但是JavaDoc还指出它不是整体。 In fact, it states that 'Applications should throw instances of this class to indicate other illegal uses of the null object.' 实际上,它声明“应用程序应抛出此类的实例以指示对null对象的其他非法使用”。 That's exactly what we do here. 这正是我们在这里所做的。
  • Expectation of the stack trace reader. 期望堆栈跟踪读取器。 Firstly, I doubt that his assumption is true. 首先,我怀疑他的假设是正确的。 If I see an IAE, I think of an illegal value . 如果看到IAE,则认为是非法价值 If I see a NPE, the problem is clear: null . 如果看到NPE,问题很明显: null Secondly, I don't think that these expectations are a valid argument here. 其次,我认为这些期望在这里不是正确的论据。 If everyone throws NPEs on null arguments, these expectations would change. 如果每个人都将NPE放在null参数上,那么这些期望将会改变。 And the fact that many people misunderstand a behaviour does not mean that it this behaviour wrong. 而且,许多人误解了一个行为并不意味着该行为是错误的。
  • IAE being more appropriate. IAE更合适。 That's a personal question. 这是一个个人问题。 As said above, I think that the NPE is more appropriate as it indicates a null value. 如上所述,我认为NPE更合适,因为它表示null值。 Since NPE is clearly designed to handle null values, why would you chose an IAE instead? 由于NPE明确设计为处理null值,因此为什么要选择IAE? ;) ;)
  • No difference between null and illegal values. null和非法值之间没有区别。 There is a difference. 有区别的。 To be honest: I do not like this. 老实说:我不喜欢这样。 I really appreciate Ceylon's approach of null being the only instance of the Null class. 我真的很感激Ceylon的null方法是Null类的唯一实例。 (In my Java code, I usually use Guava's Optional class to represent nullable variables.) But the Java authors made a clear decision: null is a very special thing, different from all other values. (在我的Java代码中,我通常使用Guava的Optional类来表示可为空的变量。)但是Java的作者做出了一个明确的决定: null是非常特殊的事情,不同于所有其他值。 This is the reason why it should be handled differently – eg with a different exception. 这就是为什么应该对它进行不同处理的原因-例如,有不同的例外。 An IAE indicates that there is something wrong with a value: maybe too short, too long, negative, positive, zero. IAE指示值存在问题:可能太短,太长,负,正,零。 A NPE indicates that there simply is no value. NPE表示根本没有价值。

An other reason why I prefer the NPE is consistent behaviour. 我更喜欢NPE的另一个原因是行为稳定。 From the caller's point of view – assuming that I do not know the method implementation – I have to assume that calling a method with a null argument will cause a NPE once this argument is accessed. 从调用者的角度来看-假设我不知道该方法的实现-我必须假设调用该参数为null的方法将导致NPE。 Throwing a NPE on manual checking does not change this behaviour. 将NPE投入手动检查不会改变此行为。 It just improves the moment the exceptions is raised. 它只是改善了引发异常的时间。

Furthermore, using NPEs allows me to omit the manual check in very simple methods, eg: 此外,使用NPE可让我以非常简单的方法省略手动检查,例如:

public void test(@Nonnull final String string) {
    string.toString();
}

I'm a bit late for the party but Java 1.7 added Objects#requireNonNull . 我参加聚会有点晚了,但是Java 1.7添加了Objects#requireNonNull

It's just a simple method which will throw a NullPointerException if the parameter is null. 这只是一个简单的方法,如果参数为null,则将引发NullPointerException I personally like this much better than failing inside the logic itself, since the method not only fails fast but one doesn't need to guess in a multiple varibales-statement which of the variables was null. 我个人喜欢这样做比在逻辑本身内部失败要好得多,因为该方法不仅快速失败,而且不需要在多重变量声明中猜测哪个变量为空。

The method returns the non-null value which is helpful for Setters and Constructors: 该方法返回非null值,这对Setter和Constructor很有帮助:

public Repot(Date reportDate, String message) {
    this.reportDate = Objects.requireNonNul(reportDate);
    this.message = Objects.requireNonNul(message);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM