首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么不让Jave方法返回一个元组而不是一个对象引用(或null)?

为什么不让Jave方法返回一个元组而不是一个对象引用(或null)?
EN

Stack Overflow用户
提问于 2014-07-05 10:54:55
回答 1查看 426关注 0票数 0

典型的Java方法如下所示:

代码语言:javascript
复制
public <U,V> U doSomething(V aReference) {
    // Do something
}

这通常意味着,如果方法doSomething()失败(无论出于何种原因)或有效的对象引用,它将返回一个null。在某些情况下,“有效对象引用”本身可能是null。例如,方法aMap.get(k)可能返回null,如果没有键k,或者如果有键k,但对应的值是null。混乱!

更别提NullPointerException了,如果50%的LOC不仅仅是空检查的话。

像这样的方法有什么问题:

代码语言:javascript
复制
public <T> ReturnTuple<T> doSomething(V aReference) {
    T anotherObjRef = getValidObjT();
    if (successful) {
        return ReturnTuple.getSuccessTuple(anotherObjRef);
    } else {
        return ReturnTuple.getFailureTuple("aReference can't be null");
    }
}

其中定义了类ReturnTuple<T>,如下所示:

代码语言:javascript
复制
class ReturnTuple<T> {
    private boolean success;

    // Read only if success == true
    private T returnValue;

    // Read only if success == false
    private String failureReason;

    // Private constructors, getters, setters & other convenience methods

    public static <T> ReturnTuple<T> getSuccessTuple(T retVal) {
        // This code is trivial
    }

    public static <T> ReturnTuple<T> getFailureTuple(String failureReason) {
        // This code is trivial
    }
}

然后调用代码将如下所示:

代码语言:javascript
复制
ReturnTuple<T> rt = doSomething(v);
if (rt.isSuccess()) {
    // yay!
} else {
    // boo hoo!
}

所以,我的问题是:为什么这种模式不更常见?这是怎么回事?

请记住,我要求的不是对这个精确代码的批评,而是对这个总体想法的批评。

请注意:这里的要点不是让上面的代码编译,只是为了讨论一个想法。所以,请不要对代码的正确性过于迂腐:-)。

编辑1:动机

我想我应该从一开始就增加这一节,但迟到总比不.

  • 是否曾希望一个方法能够同时返回两个值?或者一个值的返回可以与表示成功或失败的能力脱钩?
  • 这也可能促进一种方法是一个整洁、干净、独立的单元(低耦合和高内聚)的想法:处理在执行过程中生成的所有(或大多数)异常(不涉及像IllegalArgumentException这样的异常),谨慎地记录失败原因(而不是隐藏异常的丑陋堆栈跟踪),并且只让调用者使用所需的确切信息。这也促进了信息隐藏和封装。
  • 尽您最大的努力进行测试,但是当代码被部署到客户时,异常的丑陋堆栈跟踪会使它看起来非常不专业。
  • 类似于上面的一点:您可能有可能生成20个不同异常的代码,但您只捕获其中的5-7个。我们都知道,客户做的是最糟糕的事情:依赖他们导致所有其他潜在的13-15例外:-)。当他们看到一个很大的堆栈跟踪(而不是添加到日志中的一个离散的失败原因)时,您的结果会很糟糕。 这就是在web应用程序中向用户显示堆栈跟踪与显示格式良好的5xx错误页面之间的区别:“出现了错误,您的请求无法完成。管理员已经收到通知,并将尽快修复。”等。

这种想法并非完全没有价值,因为Java 8提供了可选类(正如@JBNizet所指出的那样),而谷歌的番石榴库也有一个可选类。这只会让事情进一步发展。

EN

回答 1

Stack Overflow用户

发布于 2014-07-05 11:08:36

这通常意味着如果方法doSomething()失败,它将返回null。

不,这并不意味着。这意味着doSomething()方法有时可以合法地返回null,而不会失败。Java为处理故障提供了一个强大的系统,即异常处理。这就是API应该如何指示失败的方式。

为什么这种返回元组模式不更常见呢?这是怎么回事?

这种模式的主要错误之处在于它使用了一种与Java无关的报告失败的机制。如果您的API运行失败,抛出一个异常。这样可以避免在“主流”情况下创建两倍于所需的对象,并使您的API能够直观地为熟悉Java类库的人所理解。

在有些情况下,返回null可以被解释为两种方式--失败和合法的返回值。在关联容器中查找对象提供了一个很好的例子:当您提供一个不在映射中的键时,您可以声称这是一个编程错误,并抛出一个异常(.NET类库这样做),或者声称当键丢失时,映射中相应的位置包含默认值,即null --这是在Java中这样做的。在这种情况下,返回一个元组是完全可以接受的。Java的Map决定不这样做,很可能会在每次从Map请求对象时节省创建额外的对象。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24585677

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档