这个问题几乎被“回答到死”了,但我认为还有几点可以有用:
1 - 最近版本的 Java 中的 JIT 可以优化异常处理,以在某些情况下大幅减少开销。但是,默认情况下不启用这些优化。
您编写示例的方式也存在问题:
捕捉Exception
是非常糟糕的做法,因为您有可能会意外捕捉到其他未经检查的异常。例如,如果您在调用时这样做,raw.substring(1)
您也会捕获潜在StringIndexOutOfBoundsException
的 s ... 并隐藏错误。
您的示例试图做的(可能)是处理null
字符串的不良实践的结果。作为一般原则,您应该尽量减少null
字符串的使用,并尝试限制它们(有意的)传播。在可能的情况下,使用空字符串而不是null
表示“无价值”。当您确实遇到需要传递或返回null
字符串的情况时,请在您的方法 javadocs 中清楚地记录它。如果您的方法null
在不应该被调用的时候被调用...这是一个错误。让它抛出一个异常。不要试图通过(在此示例中)返回来补偿错误null
。
我的问题更笼统,不仅仅是null
价值观。
...而且我回答中的大部分观点都与null
价值观无关!
但请记住,在许多情况下,您希望允许偶尔出现空值或任何其他可能产生异常的值,然后忽略它们。例如,当从某个地方读取键/对值并将它们传递给像上面的 tryTrim() 这样的方法时,就是这种情况。
是的,在某些情况下null
需要值,您需要处理它们。
但我会争辩说,tryTrim()
正在做的事情(通常)是错误的处理方式null
。比较这三位代码:
// Version 1
String param = httpRequest.getParameter("foo");
String trimmed = tryTrim(param);
if (trimmed == null) {
// deal with case of 'foo' parameter absent
} else {
// deal with case of 'foo' parameter present
}
// Version 2
String param = httpRequest.getParameter("foo");
if (param == null) {
// deal with case of 'foo' parameter absent
} else {
String trimmed = param.trim();
// deal with case of 'foo' parameter present
}
// Version 3
String param = httpRequest.getParameter("foo");
if (param == null) {
// treat missing and empty parameters the same
param = "";
}
String trimmed = param.trim();
最终,您必须处理与null
常规字符串不同的问题,并且通常尽快这样做是个好主意。允许从其原点传播得越远null
,程序员就越有可能忘记值是一种null
可能性,并编写假定非空值的错误代码。忘记可能缺少 HTTP 请求参数(即param == null
)是发生这种情况的典型案例。
我并不是说这tryTrim()
本质上是坏的。但是,您觉得需要编写这样的方法这一事实可能表明空值处理不太理想。
最后,还有其他方法可以在 API 中对“没有价值”进行建模。这些包括:
- 测试
null
setter 和构造函数中的意外情况,然后抛出异常或替换不同的值。
- 添加一个方法...如果结果是. 则
is<Field>Set
抛出异常。get<Field>
null
- 使用空对象模式。
- 使用空字符串、空集合、零长度数组等代替
null
字符串、集合或数组1。
- 使用
Optional
.
1 - 请注意,这与 Null 对象模式不同,因为不一定只有一个类型的实例来表示“nullity”。但是您可以将这两个想法结合起来……如果您对此有纪律的话。