gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 22:52:18 26 4
gpt4 key购买 nike

通常 Java 方法如下所示:

public <U,V> U doSomething(V aReference) {
// Do something
}

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

更不用说NullPointerException如果你的 LOC 的 50% 不只是空检查。

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

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

所在类(class)ReturnTuple<T>定义如下:

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

那么调用代码将如下所示:

ReturnTuple<T> rt = doSomething(v);
if (rt.isSuccess()) {
// yay!
} else {
// boo hoo!
}

所以,我的问题是:为什么这种模式没有更常见?这是什么问题?

请记住,我并不是要求对这段确切的代码进行批评,而是要求对对这一总体想法的批评。

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

编辑 1:动机

我想我应该从一开始就添加这一部分,但最好晚点添加比从来没有...

  • 是否曾经希望一个方法可以同时返回两个值?或者说返回的一个值的大小可以与指示成功的能力脱钩,或者失败?

  • 这也可以促进方法干净整洁的想法自包含单元(低耦合和高内聚):处理所有(或大多数)执行过程中产生的异常(不是谈论异常喜欢 IllegalArgumentException ),谨慎地记录失败原因(而不是比未捕获的异常的丑陋堆栈跟踪)并且只会打扰调用者准确提供所需信息。恕我直言,这也促进了信息隐藏和封装。

  • 尽最大努力进行测试,但是当代码部署给客户时,未捕获的异常丑陋的堆栈跟踪使一切看起来如此不专业。

  • 与上述类似:您可能有可能生成20 种不同的异常,但您只捕获其中的 5-7 个。正如我们大家一样知道,客户做了最糟糕的事情:依靠他们来引起所有其他事情未捕获 13-15 个异常:-)。当他们看到一个大的东西时,你最终看起来很糟糕堆栈跟踪(而不是添加到日志中的离散失败原因)。

    这是(例如)显示堆栈跟踪与Web 应用程序中的用户 vs. 向他们展示格式良好的 5xx 错误页面:例如:“出现错误,无法完成您的请求。管理员已收到通知,将尽快修复。”等

这个想法并非完全没有优点,因为 Java 8 提供了 Optional类(正如 @JBNizet 所指出的)和 Google 的 Guava图书馆还有一个 Optional类(class)。这只是更进一步。

最佳答案

This typically means that the method doSomething() returns a null if it fails

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

why isn't this [return a tuple] pattern more common? What is wrong with it?

这种模式的主要错误是它使用了一种与 Java 不同的方式报告失败的机制。如果您的 API 遇到故障,请抛出异常。这使您不必创建“主流”情况下所需数量的两倍的对象,并且使熟悉 Java 类库的人能够直观地理解您的 API。

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

关于java - 为什么 Jave 方法不返回一个元组而不是一个对象引用(或 null)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24585677/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com