如何在一个函数中避免返回 NULL 值?(JAVA)

7

假设我有一个 List<SomeObject>,并且有一个函数,如果可用,则返回该对象的引用。

SomeObject GetSomeObject(List<SomeObject>, int x){
    /* Search for object in list that has a properties
        with value x */

    if (found)
        return /* The object found */
    else
        return NULL;
}

void DoSomething(SomeObject S){
    if(S!=NULL){
        /* Do action 1 */
    }
    else{
        /* Do action 2 */
    }
}

我曾在某处看到过,返回NULL不是干净代码的一部分。 所以我想知道这种情况的等效代码是什么。

更新:我读了这个问题,我认为我的情况是不同的。 在那种情况下,如果返回NULL,则什么也不做,而如果返回NULL,则我需要执行某些操作。


1
作为答案的附注 - 这不是C#,在Java中方法名应该以小写字母开头(这是非常强烈的Java约定)。 - amit
根据我在那个问题的解决方案中所读到的,我认为那个问题更像是如果找不到则什么也不做,而我需要在返回空值时执行某些操作。@amit 哦,好的,谢谢你提醒我。 - jamesalone
有人能给出在其示例上下文中使用Optional的示例吗?他的函数返回一个对象,在示例中该对象可能不在列表中,这意味着他要么返回null,要么抛出异常。如何使用Optional解决这个问题? - JohannisK
4个回答

6
如果您正在使用Java 8,请考虑Optional类,但请注意它并不适用于所有情况。
许多人认为(包括我在内)Optional应仅用于返回值,而不是参数,尤其不是对象属性。然而像往常一样,没有硬性规定,只需小心不要盲目地用Optional替换空处理,而不了解是否从中获得任何优势。
例如,在示例代码中,Optional对您没有任何好处。由于您执行某些操作而不管null还是非null,因此您只需要将if(s == null)更改为if(s.isPresent())。但是,如果逻辑仅在s非null时执行某些操作,而没有else,则可以使用Optional.ifPresent()使事情变得更加清晰。当然,Optional中还有其他有用的方法,例如orElse(),可有效地用于使用默认值。

1
我认为值得一提的是Guava的Optional - ericbn

5

看起来你是指特殊情况模式(具体实现包括OptionNull Object模式)。

Java中有Option类型的实现,被命名为Optional,分别在Java 8Guava库中。

在你的情况下,你将使用Optional<SomeObject>并采用这种实现方式(我使用的是Guava实现):

Optional<SomeObject> getSomeObject(List<SomeObject>, int x) {
    /* Search for object in list that has a properties
        with value x */
    if (found) {
        return Optional.of(objectFound);
    } else {
        return Optional.absent(); // or Optional.empty(); in Java 8
    }
    // if objectFound variable is null when not found, you can simply use
    // return Optional.fromNullable(objectFound);
    // or return Optional.ofNullable(objectFound); in Java 8
}

所以,代码对于返回可选对象是自解释的。您将会有以下内容:
void doSomething(Optional<SomeObject> o) {
    if (o.isPresent()) {
        SomeObject someObject = o.get();
        /* Do action 1 */
    } else {
        /* Do action 2 */
    }
    // or opt.map(/* action 1 */).orElse(/* action 2 */); in Java 8
}

1
你可以抛出 NoSuchElementException,这符合"快速失败"的方法论。
然而,如果你的代码开始使用异常机制进行流程控制,那么这是非常不好的做法,应该避免使用。 一个很好的经验法则是,如果元素不存在,只有当你的API也支持contains()(或HasSomeObject(obj))方法时才抛出异常。
免责声明:本答案适用于Java 8之前的代码,对于Java 8,更好的做法可能是使用Optional,如@Kayman所建议的那样

@ericbn 我也提供了他应该做什么(同时实现hasSomeObject())。 - amit

1

你可以考虑使用 空对象模式,这是一种常见的方法。

与其返回NULL,不如返回正确对象类型的实例,当你调用它的方法时,它什么也不做。这并不适用于所有情况,但值得思考。


我刚刚读了这个,但是如果我想在列表中找不到对象时做些什么呢? - jamesalone
这实际上取决于你想做什么。如果代码采取完全不同的路径,那么这种模式可能不是你想要的。在你的例子中,每种情况(找到对象与未找到对象)会发生什么(简要说明)? - DaveH
我正在尝试根据对象是否被找到来过滤列表。如果找到了对象,则根据对象的属性进行过滤,而如果未找到,则进行不同的过滤。 - jamesalone

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