返回null;这是必需的,因为可能会捕获到异常,但是在这种情况下,因为我们已经检查了它是否为null(并假设我们知道我们正在调用的类支持克隆),所以我们知道try语句永远不会失败。
如果您以知道try
语句永不失败的方式了解有关输入的详细信息,那么拥有它的意义何在?避免try
如果您确定可以确保事情总是成功则(尽管很少有人可以在代码库的整个生命周期中绝对确信)。
无论如何,不幸的是,编译器不是心智的读者。它可以看到函数及其输入,并获得其所拥有的信息,因此,它需要return
在底部具有该语句。
只是为了满足语法并避免编译错误(在注释中说明将不会到达)而在末尾添加额外的return语句是不好的做法,还是有更好的方法编写这样的代码以使额外的内容返回语句是不必要的吗?
相反,我建议最好避免任何编译器警告,即使这样做会花费另一行代码。在这里不必太担心行数。通过测试建立功能的可靠性,然后继续进行。只是假装您可以省略该return
语句,想象一下在一年后返回该代码,然后尝试确定return
底部的该语句是否会引起混乱,而不是某些注释详细说明了为什么由于假设而被省略的细节。输入参数。最有可能return
声明会更易于处理。
也就是说,特别是关于这部分:
try {
return a.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
...
return null;
我认为这里的异常处理思维方式有些奇怪。通常,您希望在可以做出响应的有意义的站点上吞下异常。
您可以将其try/catch
视为一种交易机制。try
进行这些更改(如果它们失败),然后我们进入该catch
块,则catch
作为回滚和恢复过程的一部分,执行此操作(无论该块中有什么)。
在这种情况下,仅打印stacktrace然后被迫返回null并不完全是事务/恢复心态。该代码将错误处理责任转移给所有代码调用,getClone
以手动检查故障。您可能更喜欢抓住CloneNotSupportedException
并将其转换为另一种更有意义的异常形式并抛出该异常,但是在这种情况下,您不想简单地吞下该异常并返回null,因为这不像事务恢复站点。
当抛出异常可以避免这种情况时,您最终将责任泄露给调用者以手动检查和处理失败。
就像您加载文件一样,这是高级事务。您可能在try/catch
那里。在trying
加载文件的过程中,您可能会克隆对象。如果此高级操作(加载文件)中的任何地方出现故障,您通常都希望将异常一直抛出到该顶级事务try/catch
块,以便您可以从加载文件的故障中正常恢复(无论是由于克隆错误或其他原因)。因此,我们通常不希望只在这样的粒度位置吞下异常,然后返回null,例如,因为那样会破坏很多异常的价值和目的。相反,我们希望将异常一直传播到可以有意义地处理它的站点。
Object
参数。如果a
不是支持该clone
方法的类(或是否在Object
?中定义),或者该clone
方法期间发生错误(或我现在无法想到的任何其他错误),则可能引发Exception,并且您将到达返回语句。