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

查看:42
本文介绍了番石榴 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();

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

我应该使用

checkNotNull(myObject).getAnything();

如果myObject 为空,则抛出NullPointerException,如果不为空,则返回myObject.

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;
    }
}

调用 accept(null) 将导致 NPE 被抛出——但不会在 stringsSeen 增加之前.这可能不是您想要的;作为该类的用户,我可能期望如果它不接受空值,那么如果传递空值,它的状态应该保持不变(换句话说:调用应该失败,但它不应该使对象无效).显然,在这个例子中,你也可以通过在增加 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天全站免登陆