使用Collections.emptyList()和空值处理

5

说到处理Java中的"null"最佳实践(特别是"List"返回值),从一个实体类的getMethod方法返回"Collections.emptyList()"是否是一个好习惯?还是我们应该使实体/数据类/方法整洁,始终返回其值(即使其为空),然后在代码的其他位置处理该空值,例如:

Class Reference{

private Reference reference;

@XmlElement(name = "Reference")
public List<Reference> getReference() {
    if(reference==null){
        return Collections.emptyList();
    }
    return reference;
}

public void setReference(List<Reference> reference) {
    this.reference = reference;
}
}

是不是最好在使用基本的get方法之后处理那个null值呢?

编辑/警告:针对我的情况,我注意到这种方法会导致我的代码崩溃,我不知道为什么,当我稍后调用时;

References ref= (References) jaxbUnmarshaller.unmarshal(xmlReader)

我遇到了一个不支持的操作异常,但是当我从collections.emtpyList中清除我的getMethod时,它可以正常工作。因此,在使用@XmlElement标签时要谨慎。
5个回答

3
一般来说,null 和“空的”在语义上是有所区别的:null表示“不存在”,而“空的”表示“存在,但里面没有东西”。如果你的类无法区分“不存在”和“空的”,那么返回一个空集合会更好:它可以避免在所有调用者中使用if语句,使他们的代码看起来更加简洁。此外,在这种情况下,我会将this.reference初始设置为Collections.emptyList(),并从getter方法中删除一个if。当然,在这种情况下,你的setter方法需要检查其参数是否为null

3
根据我的经验,“按合同编程”或“按合同设计”(链接)通常用于编写Java代码。
这意味着,在您的示例中,如果您的引用未由外部实体设置,则只需返回null。

2
“确实将非空集合返回是一个好的做法。这可以避免每个调用者都需要执行…”
if (list != null) {
    for (Item i : list) {
        ...
    }
}

上述代码是可以的。但是,如果禁止reference变量中有任何空值,那就更好了。如果您为列表设置了setter,那么如果传递的列表为空,就让它抛出异常,或将null转换为一个空集合。这样,甚至您类内部的代码也不必担心引用变量为空。
如果您需要区分空列表和null,请考虑使用Guava的Optional类,这会使事情更加清晰。
只是一点提示:由于您有一个列表,变量应该被命名为references(带有最后的s),访问器应该被命名为getReferencessetReferences

谢谢,所有的建议都很好。我们可以说,在实体类中处理 null 值的方法也适用于非 List 类型,比如字符串或整数吗? - Spring
只有在需要将变量设置为可空时,才会使用Integer而不是int。否则,使用int是更好的选择。关于String,通常使用null表示属性未设置,而不是空字符串。但调用者通常不会迭代String字符。 - JB Nizet
仅针对我的情况,这种方法会导致我的代码崩溃,我不知道为什么。当我稍后调用(References) jaxbUnmarshaller.unmarshal(xmlReader)时,我会得到一个不支持的操作异常,并且只有在我从collections.emtpyList中清除我的getMethod时才能正常工作。 - Spring

1
一般来说:这取决于您是否需要区分缺失列表和空列表。
在访问 XML 库的情况下,似乎有一个惯例始终返回一个可变列表,以便您可以通过它更新实体。至少所有自动生成的 WS-* 代码都是如此。
例如,要添加引用,您将执行以下操作。
x.getReferences().add(someReference);

如果您返回null,那将导致异常。

另一方面,该约定没有或不需要引用列表的setter(您只需清除列表并添加所有内容,而不是设置新列表)。


1
private Reference reference = Collections.emptyList();

public List<Reference> getReference() {
    return reference;
}

public void setReference(List<Reference> reference) {
    if(reference==null) 
        reference = Collections.emptyList();
    this.reference = reference;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接