番石榴checkNotNull有什么意义 [英] What's the point of Guava checkNotNull

查看:129
本文介绍了番石榴checkNotNull有什么意义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Guava的新手(说实话,我不是非常新的,我是这个主题的完整新手)所以我决定通过一些文档并在阅读本文时非常惊讶:

I'm pretty new to Guava (let's be honest, I'm not "pretty new", I'm a complete rookie on that subject) and so I decided to go through some documentation and got quite amazed while reading this:

com.google.common.base.Preconditions.checkNotNull(...)

我不明白这个方法的意义。
这意味着代替:

I don't get the point of this method. This means that instead of doing :

myObject.getAnything();

(这可能导致 NullPointerException 如果myObject为null)

(which might cause a NullPointerException if myObject is null)

我应该使用

checkNotNull(myObject).getAnything();

抛出 NullPointerException if myObject 为null并返回 myObject 如果它不为null。

which will throw a NullPointerException if myObject is null and return myObject if it is not null.

我很困惑,这可能是有史以来最愚蠢的问题但是......

I'm puzzled and this might be the stupidest question ever but ...

这有什么意义呢?
这两行与我能想到的任何情况完全相同。

What is the point of this? Those two lines do the exact same thing as for outcomes given any situations I can think of.

我甚至认为后者更具可读性。

I don't even think that the latter is more readable.

所以我必须遗漏一些东西。它是什么?

So I must be missing something. What is it?

推荐答案

想法是快速失败。例如,考虑这个愚蠢的类:

The idea is to fail fast. For instance, consider this silly class:

public class Foo {
    private final String s;

    public Foo(String s) {
        this.s = s;
    }

    public int getStringLength() {
        return s.length();
    }
}

假设你不想允许空值对于 s 。 (否则 getStringLength 将抛出NPE)。随着类的原样,当你捕获 null 时,已经太晚了 - 很难找到谁把它放在那里。罪魁祸首很可能是一个完全不同的类,而且很久以前就已经构建了 Foo 实例。现在你必须梳理你的代码库,找出谁可能在那里放一个 null 值。

Let's say you don't want to allow null values for s. (or else getStringLength will throw a NPE). With the class as-is, by the time you catch that null, it's too late -- it's very hard to find out who put it there. The culprit could well be in a totally different class, and that Foo instance could have been constructed a long time ago. Now you have to comb over your code base to find out who could possibly have put a null value there.

相反,想象一下这个构造函数:

Instead, imagine this constructor:

public Foo(String s) {
    this.s = checkNotNull(s);
}

现在,如果有人提出 null 在那里,你会立即找到 - 你将拥有堆栈跟踪指向你错误的电话。

Now, if someone puts a null in there, you'll find out right away -- and you'll have the stack trace pointing you exactly to the call that went wrong.

另一个有用的方法是,如果要在执行可以修改状态的操作之前检查参数。例如,考虑这个类计算它获得的所有字符串长度的平均值:

Another time this can be useful is if you want to check the arguments before you take actions that can modify state. For instance, consider this class that computes the average of all string lengths it gets:

public class StringLengthAverager {
    private int stringsSeen;
    private int totalLengthSeen;

    public void accept(String s) {
        stringsSeen++;
        totalLengthSeen += s.length();
    }

    public double getAverageLength() {
        return ((double)totalLengthSeen) / stringsSeen;
    }
}

调用接受(null) 会导致NPE被抛出 - 但是在 stringsSeen 之前不会增加。这可能不是你想要的;作为类的用户,我可能期望如果它不接受空值,那么如果传递null,它的状态应该保持不变(换句话说:调用应该失败,但它不应该使对象无效)。显然,在这个例子中,您还可以通过在递增 stringsSeen 之前获取 s.length()来修复它,但是你可以看看如何使用更长且更复杂的方法,首先检查所有参数是否有效,然后只修改状态可能很有用:

Calling accept(null) will cause an NPE to get thrown -- but not before stringsSeen has been incremented. This may not be what you want; as a user of the class, I may expect that if it doesn't accept nulls, then its state should be unchanged if you pass a null (in other words: the call should fail, but it shouldn't invalidate the object). Obviously, in this example you could also fix it by getting s.length() before incrementing stringsSeen, but you can see how for a longer and more involved method, it might be useful to first check that all of your arguments are valid, and only then modify state:

    public void accept(String s) {
        checkNotNull(s); // that is, s != null is a precondition of the method

        stringsSeen++;
        totalLengthSeen += s.length();
    }

这篇关于番石榴checkNotNull有什么意义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆