我已阅读此主题:避免!= null 语句,但我没有看到好处。
如果返回空数组,则需要检查“真实”数组在哪里,以及空数组在哪里。
而不是使用类似的代码
getName() != null
,您必须使用getName().length > 0
. 举个例子,我正在做一个项目,我需要用很少的存档器压缩一些数据,并决定选择最小大小的压缩数据。如果我从归档程序“压缩”方法返回 null,我需要检查返回的值是否不为 null。如果我决定返回一个空数组,那么我还需要检查它是否为空。
我对吗?
我已阅读此主题:避免!= null 语句,但我没有看到好处。
如果返回空数组,则需要检查“真实”数组在哪里,以及空数组在哪里。
而不是使用类似的代码getName() != null
,您必须使用getName().length > 0
. 举个例子,我正在做一个项目,我需要用很少的存档器压缩一些数据,并决定选择最小大小的压缩数据。如果我从归档程序“压缩”方法返回 null,我需要检查返回的值是否不为 null。如果我决定返回一个空数组,那么我还需要检查它是否为空。
我对吗?
使用空集合或“空白”操作而不是 null 的主要优点是,大多数情况下,此类对象仍可在代码中工作而无需进一步修改。该null
值的核心是由于其性质而更容易出错。
以下面的代码为例:
String[] names = data.getNames();
if (names != null) {
for (String name : names) {
// Do stuff
}
}
检查null
是必需的,否则您将获得 NPE。使用标准 for 循环并不能解决问题。另一方面,如果你知道你总是会得到某种类型的数组,那么你的代码将可以正常工作而无需额外的检查。如果数组为空,则循环根本不会运行。问题解决了。
对于实现某种形式的操作的代码也是如此。另一个例子:
Action myAction = data.getActionToRun();
if (myAction != null) {
myAction.run();
}
再一次,你需要一张null
支票。如果该动作保证存在,那么您始终可以调用action.run()
而没有副作用,但空白动作不会做任何事情。就是这么简单。
在许多情况下,null
如果您修改方法返回的方式,则可以简单地丢弃检查,从而生成更简单且易于理解的代码。在某些情况下,返回null
是正确的选择(例如,从键和值的集合中获取对象),因为没有默认的“无动作”值。但是null
表示根本没有值,并且需要接收方进行额外处理。使用空白、无操作、非空对象允许数据对象处理错误。这是很好的封装。是很好的编程。它只是工作。™</p>
最后,返回null
肯定不是处理错误的好方法。如果您的代码中出现错误,除非您作为程序员犯了编程错误,否则永远不会assert
出错,请使用s 或异常。这些都是失败。不要null
用作失败案例,将其用作简单的缺少值。
空数组有时是更自然的返回对象。考虑一些这样的代码:
String [] elements = getElements();
for (String element : elements)
System.out.println(element);
如果您返回一个空数组(即没有元素),则不会打印任何内容并且代码将正确执行。但是,如果 getElements() 返回 null,您将得到一个空指针异常。为了防止它,您需要添加更多代码,这会使事情变得更加复杂。返回一个空数组允许在没有额外代码的情况下发生所需的行为。
我有过这样的想法。暂时搁置 NPE 问题。我将尝试从 OOP 的角度解释我的想法。
假设您编写了一个为 Glass 实例提供 getter 的类
public Glass getGlass()
。当我读到这个签名时,我期待的是 Glass 接口的一些实例,而 null 不是一个。
你可以考虑下一种方法public Optional<Glass> getGlass()
。
Optional 类(可以编写您自己的或使用Google 的 guava Optional)包含您的通用类实例,同时提供isPresent函数等。这似乎是多余的原因'您可以只使用getGlass() != null
而不是getGlass().isPresent()
从您的客户端代码中使用。但这里的主要优点是签名很简单。没有人隐瞒什么,你也不必猜测。
因此,您将获得以下好处: