Java 覆盖控制流/性能的fillInStackTrace

Java 覆盖控制流/性能的fillInStackTrace,java,exception,Java,Exception,注意:虽然看起来很相似,但这不是 对于将选中异常上的fillInStackTrace重写为返回null,您有什么想法 优点是: 您可以将所述异常用于控制流,而不会因填充堆栈跟踪而导致性能损失 您可以将任意对象作为异常的属性传递回调用方,而不考虑引发该异常的方法的签名。(例如,错误消息、部分初始化值等) 最大的缺点就是这不是标准做法 但做类似事情的唯一方法是: 返回null,或返回一个“特殊值”(例如-1),表示出现了问题 更改被调用方以返回值和错误代码的复合对象,并让调用方检查此对象以查看发生了

注意:虽然看起来很相似,但这不是

对于将选中异常上的fillInStackTrace重写为返回null,您有什么想法

优点是:


  • 您可以将所述异常用于控制流,而不会因填充堆栈跟踪而导致性能损失
  • 您可以将任意对象作为异常的属性传递回调用方,而不考虑引发该异常的方法的签名。(例如,错误消息、部分初始化值等)
  • 最大的缺点就是这不是标准做法

    但做类似事情的唯一方法是:

  • 返回null,或返回一个“特殊值”(例如-1),表示出现了问题
  • 更改被调用方以返回值和错误代码的复合对象,并让调用方检查此对象以查看发生了什么
  • 我正在寻找一个非常有说服力的论点,支持或反对覆盖fillInStackTrace的做法,或者一个表明这两种方式都没什么大不了的论点

    显然RIFE使用了这种技术:


    下面是做某事的标准方法,以及使用此技术的人为示例

        //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");
        }
    
    //标准
    int i=“foo”。indexOf('f');
    
    如果(i如果您认为必须这样做,您可能会使用良好的重构

    我的一般想法是,有一个失败的状态,您正试图返回到树上。如果该状态是在一个公共对象中设置的,那么该状态将只是在那里被查询

    你确定每个对象只做一件事吗?你的对象在任何可能达到的状态下都有效吗

    作为一个目标,如果你的对象超过10个方法,大多数方法是1行或2行,一些方法是满屏的,那么你可能需要更多的类,正如我所说的,如果你有足够的类并且它们有一个一致的状态,这个问题几乎肯定会消失

    评论中的示例: 在注释中,asker使用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...
    
    由于创建了新的异常类型,它的优点是更加自文档化,但有一些不寻常的语法,需要创建一个新类(异常)

    我的建议可能是也创建一个新类,但请按以下方式编写:

    Position pos=str.indexOf('a');
    if(!pos.characterFound())
        System.out.println("Fail");
    else
        // do something with pos.location();
    
    自我记录,更快(有例外的堆栈POP总是较慢),等等

    但正如我最初所说的,最大的优点是新类“pos”。它可能会非常有用。事实上,您可以不使用pos.location,而是将代码从“pos”中方法的“else”子句中移动,将其完全删除

    因为它可以包含业务逻辑,所以该方法实际上可以由.indexOf调用本身执行,从而完全消除调用周围的if语句


    这对于像indexOf这样的“泛型”库方法没有多大意义,这有点遗憾,但SDK方法确实很难在适当的OO中实现,但在您自己的业务逻辑中,您几乎肯定会找到这个新的“位置”类在将来非常有用。

    我认为这没关系。有时你别无选择。但我发现“返回值时的if-else”代码通常比“异常时尝试捕获”代码更易于编写和读取。

    你可以将所述异常用于控制流你说这是一种优势?别提第二条!为什么任何头脑清醒的人都想在返回值类型上作弊?@Martinho。是的,我声称增加更多/不同的做事方式可能是一种优势,有时会带来权衡。我个人认为总是坚持你知道的,而忽略其他可能性是疯狂的这些都不是问题。想想“什么”.indexOf返回。它不返回字符的索引。它返回一个数字,如果该数字>=0,那么您就有了索引。如果该数字是indexOf,则有点麻烦。他们正在将附加数据破解为int。虽然这有时会使事情变得更简单,但它可以由两种机制替代——您可以将其拆分为两个calls(测试它是否存在,然后获取索引)或者您可以返回一个带有索引和布尔值的对象。两者都绝对比处理异常更清晰,代码也更少,老实说,两者都可能比当前的indexOf实现更清晰,唯一的例外是当前的indexOf将所有信息保存在一个调用中(这在理解SDK时有一些优势)所有的优点。我已经接受了你的答案,因为它包含了更多的信息。正如我在文章中提到的,我一直在考虑创建一个具有值和(错误)状态的通用结果类,以便在这种情况下使用。
    Position pos=str.indexOf('a');
    if(!pos.characterFound())
        System.out.println("Fail");
    else
        // do something with pos.location();