【问题标题】:Is it possible to use exceptions as conditions?是否可以使用异常作为条件?
【发布时间】:2018-06-12 06:08:03
【问题描述】:

下面是我的应用程序中的一些代码:

public void run() throws myException{
    boolean gameOver = false;
    while(!gameOver){
        //do stuff, and eventually make gameOver true to end execution
...

现在是这样,我想删除布尔属性以使用用户定义的异常来结束执行。 我正在考虑检查是否在 while 条件下抛出了这个异常,只要它没有被抛出就一直循环。

类似的东西

while(myException.notThrown){

这个可以吗?

【问题讨论】:

  • 你能解释一下为什么这比使用布尔标志更好吗?
  • 您可以只使用while(true),因为当您在循环内执行throw new myException(); 时,当前方法的执行无论如何都会停止。当然,这是否是好的设计是另一个问题。
  • 发生“异常”时抛出异常。您的程序未设置为处理的意外事件。游戏结束事件似乎也不例外。
  • 您应该阅读 Effective Java 2nd Ed 第 57 条:“仅在异常情况下使用异常”以了解为什么这不是一个好主意。
  • 每次运行程序都会发生一次,这并不例外

标签: java exception conditional-statements


【解决方案1】:

你可以用一个无限的while和一个break。如果发生异常,您将中断 while。

while (true) {
    try {
        ...
    } catch (YourException e) {
        break;
    }
}

【讨论】:

  • 或者在 try 中使用一个无限循环,并带有空的 catch。无需休息
【解决方案2】:

但是为什么呢?如果你真的需要它,你可以做一个无限循环来做,你可以做类似的事情

while (true) {
    try {
        // some code to throw an exception
    } catch(Exception e) {
        e.printStackTrace();
        break;
    }
}

更新你可以将内循环变成异常

try {
    while (true) {
        // some code to throw an exception in order to remove the break keyword
    }
} catch (Exception e) {
    e.printStackTrace();
}

【讨论】:

    【解决方案3】:

    可以这样做吗?

    是的,你可以这样做:

    public class Example {
        public static void run() throws IOException {
            if (Math.random() > 0.75) {
                throw new IOException();
            }
        }
        public static void main(final String... args) {
            boolean thrown = false;
            while (!thrown) {
                System.out.println("Roll");
                try {
                    run();
                } catch (IOException ex) {
                    thrown = true;
                }
            }
            System.out.println("Done");
        }
    }
    

    在示例滚动中会输出:

    Roll
    Roll
    Roll
    Roll
    Roll
    Done
    

    应该这样做

    这可能是个坏主意,因为它会使代码更难阅读、更难维护,并且引发异常的开销也可能会使代码变慢。

    【讨论】:

      【解决方案4】:

      您的问题的答案是,但这种结构的实现取决于您的需求。

      直接(和不恰当)的方式是:

      public void run() {
          MyException ex = null;
          while(ex == null) {
              try {
                  // Do stuff
              } catch(MyException e) {
                  // Maybe handle this exception
                  ex = e;
              }
          }
      }
      

      但这是一种奇怪的逻辑形式,可以简化为:

      public void run() {
          while(true) {
              try {
                  // Do stuff
              } catch(MyException e) {
                  // Maybe handle this exception
                  break;
              }
          }
      }
      

      或者这个,这是我对这三个的偏好:

      public void run() {
          try {
              while(true) {
                  // Do stuff
              } 
          } catch(MyException e) {
             // Maybe handle this exception
          }
      }
      

      尽管有所有这些可能性,因为您的 run 签名中已经有 throws MyException,假设您的调用者正确处理它,您可以这样做:

      public void run() throws MyException {
          while(true) { // Or maybe some exit condition?
              try {
                  // Do stuff
              }
          }
      }
      

      这让异常传播到调用者。然后,让调用者处理产生的异常:

      try {
          myObject.run();
      } catch(MyException e) {
          // Handle this exception
      }
      

      您要使用的结构取决于您的逻辑流程。考虑哪个实体应该处理您的自定义异常。抛出这个异常意味着什么?谁/什么将负责处理此类案件?

      【讨论】:

      • 完美!正是我想要的。谢谢=]
      【解决方案5】:

      是的,这是可能的。 但对flow control is generally considered an anti-pattern 使用例外;它使代码更难阅读和调试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-13
        • 2013-04-21
        • 2019-02-16
        相关资源
        最近更新 更多