注意:虽然看似相似,但这并不是Overriding fillInStackTrace for a standard JVM Exceptions 的重复
您对覆盖已检查异常的 fillInStackTrace 以返回 null 有何想法?
优点是:
- 您可以将上述异常用于控制流,而不会因填充堆栈跟踪而导致性能下降。
- 您可以将任意对象作为异常的属性传递回调用者,而不管抛出所述异常的方法的签名如何。 (例如错误消息、部分初始化的值等)
最大的缺点就是这不是标准做法。
但是做类似事情的唯一方法是:
- 返回 null 或“特殊值”(例如 -1)以表示出现问题。
- 更改被调用方以返回值和错误代码的复合对象,并让调用方检查此对象以查看发生了什么。
我正在寻找一个非常有说服力的论据来支持或反对覆盖 fillInStackTrace 的做法,或者一个表明这两种方式都没什么大不了的论据。
显然 RIFE 使用了这种技术:
http://www.rifers.org/
http://cretesoft.com/archive/newsletter.do?issue=129
下面是做某事的标准方法,以及使用此技术的人为示例。
//standard
int i = "foo".indexOf('f');
if (i<0){
System.out.println("found f");
} else {
System.out.println("no f here");
}
//example
try {
"foo".indexOf('f');
System.out.println("found f");
} catch (NotFound e) {
System.out.println("no f here");
}
最佳答案
如果您认为必须这样做,您可以使用来自良好重构的方法。
我的一般想法是存在一种失败状态,即您正试图返回树上。如果该状态设置在一个公共(public)对象中,那么该状态就在那里供查询。
您确定每个对象只做一件事情吗?您的对象在它们可能达到的任何状态下都有效吗?
作为目标,如果您的对象有 10 个以上的方法,其中大多数方法只有 1 或 2 行,少数方法占满屏幕,那么您可能需要更多的类,正如我所说,如果您实际上有足够的类并且它们有一致的状态,这个问题几乎肯定会消失。
来自评论的例子: 在评论中,提问者以 indexOf 为例——它在一个 int 中返回两个值的方式。这总是会导致一些非常直接的代码:
int pos=str.indexOf('a');
if(pos < 0) // Not obvious from code--should comment...
System.out.println("Fail");
else
//Do something with pos...
他建议用一个异常(exception)来解决这个问题,这会导致这样的代码:
try {
int pos=str.indexOf('a');
//Do something with pos...
} catch(CharacterNotFoundInStringException e) {
System.out.println("Fail");
}
由于创建了新的异常类型,它具有更多 self 记录的优势,但具有一些不寻常的语法并且需要创建一个新类(异常)。
我的建议也可能是创建一个新类,但要这样编码:
Position pos=str.indexOf('a');
if(!pos.characterFound())
System.out.println("Fail");
else
// do something with pos.location();
self 记录,更快(有异常的堆栈弹出总是更慢)等。
但正如我最初所说的,最大的优势是新类“pos”。它可能会非常有用。事实上,您可以不使用 pos.location,而是将代码从“pos”中的方法内的“else”子句中移走,将其完全删除。
由于它可能包含业务逻辑,因此 Position 中的该方法实际上可能由 .indexOf 调用本身执行,从而完全消除了调用周围的 if 语句。
这对于像 indexOf 这样的“通用”库方法来说并没有多大意义,这有点遗憾,但 SDK 方法确实很难在适当的 OO 中实现,但在你自己的业务逻辑中,你几乎肯定会发现这个新的“位置”类在未来非常有用。
关于java - 覆盖控制流/性能的 fillInStackTrace,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1836164/