强制 try 块在两者之间中断的最佳方法是什么?

发布于 2024-12-25 08:07:30 字数 606 浏览 3 评论 0原文

我有一个 try-catch 块,我希望像 switch 块一样break,但我找不到推荐的做法。我正在 try-catch 块中获取大量数据,并希望在满足特定条件时停止获取。为了让它现在正常工作,我故意强制代码进入 catch 块:

int i=0;
    try {
        //--do stuff----
        if(//-------is condition met?--------//)
            i = 1/0; // divide 1 by 0 -- a definite exception
    }
    catch (Exception e) {//---------do nothing---------//}

这样做安全吗还是应该采用其他方法?

编辑:我正在获取一些 xml 数据(实际上,很多)。根据互联网连接,我需要在一段时间(超时)后停止解析,而不是遍历整个流。我会进行循环,但稍后也会进行一些计算。用不完整的数据进行计算没有任何意义,所以我宁愿跳过整个过程。

I have a try-catch block that I wish to break like a switch block but I couldn't find a recommended way of doing it. I'm fetching a lot of data in the try-catch block and wish to stop the fetching in between in case a certain condition is met. Just to get it working for now, I've deliberately forced the code to go into the catch block:

int i=0;
    try {
        //--do stuff----
        if(//-------is condition met?--------//)
            i = 1/0; // divide 1 by 0 -- a definite exception
    }
    catch (Exception e) {//---------do nothing---------//}

Is it safe to do this or should I go for another way?

EDIT:I'm fetching some xml data(actually, a lot). Depending on the internet connection, I need to stop the parsing after sometime(time-out) rather than go through the entire stream. I go through loops but I also make some calculations later. It doesn't make any sense to calculate with incomplete data, so I would prefer to just skip the whole thing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

梦途 2025-01-01 08:07:30

这段代码有点反模式的味道,但如果没有更多的上下文,我们就无法提出更好的设计。一般来说,您应该只在程序状态中出现真正例外情况时抛出异常。您尤其不应该为正常(预期)控制流抛出异常,而应该使用控制流语句,例如循环(使用 break/continue) 并返回

如果您确实希望保留此结构(即使您不应该),那么我建议显式抛出一个特殊的异常类以明确您在做什么,例如:

public static class ConditionMetException extends Exception { }

// ...
try {
  // do stuff
  if ( /* Is condition met? */ ) {
    throw new ConditionMetException();
  }
} catch (ConditionMetException cme) { /* Do nothing. */ }

但是,您可能最好重构以使用循环和内置的 break 命令。

This code smells of some anti-pattern but without more context we can't prescribe a better design. In general, you should only throw an exception for a truly exceptional condition in the state of your program. You should especially not throw an exception for normal (expected) control flow, instead you should use control flow statements such as loops (using break/continue) and return.

If you do wish to keep this structure (even though you should not) then I suggest explicitly throwing a special exception class to make it clear what you are doing, e.g.:

public static class ConditionMetException extends Exception { }

// ...
try {
  // do stuff
  if ( /* Is condition met? */ ) {
    throw new ConditionMetException();
  }
} catch (ConditionMetException cme) { /* Do nothing. */ }

But again, you're likely better off refactoring to use a loop and the built in break command.

孤千羽 2025-01-01 08:07:30

breakthrow 都会做你想要的事情(并且 throw 会更好,你至少对你在做什么有一些可追溯性做

[编辑]

what: try {
         System.out.println ("before break");
         break what;

      } catch (Exception e) {}
   }

[/编辑]

Either break or throw will do what you want (and the throw would be preferable, you at least have some traceability as to WTH you're doing.

[edit]

what: try {
         System.out.println ("before break");
         break what;

      } catch (Exception e) {}
   }

[/edit]

ゝ杯具 2025-01-01 08:07:30

仅仅为了中断而抛出异常是不好的做法。

这对你的情况有用吗?

  1. 将当前 try 内的代码放入另一个方法 fetchLotsOfData() 中。它仍然可以抛出 IOException 或任何适当的异常。
  2. 当您想停止获取数据时,只需返回即可。也许返回一些真/假或成功状态。

所以你的最终代码是这样的

int recordsRead = -1;  // -1 means failure
try {
  recordsRead = fetchLotsOfData();
}
catch (IOException ioe) {
  // handle the exception
}

// process what you got...

Throwing an Exception just to break is bad practice.

Would this work for your situation?

  1. Put the code currently inside the try into another method, fetchLotsOfData(). It can still throw IOException or whatever is appropriate.
  2. When you want to stop doing your thing fetching the data, just return. Perhaps returning some true/false or status for the success.

So your final code is something like

int recordsRead = -1;  // -1 means failure
try {
  recordsRead = fetchLotsOfData();
}
catch (IOException ioe) {
  // handle the exception
}

// process what you got...
心头的小情儿 2025-01-01 08:07:30

我要回答“这是个好主意吗?”问题的一部分:不。

使用异常来实现预期的控制流不是一个好主意。这是可能的,但不是预期的,就像可以将所有变量设置为字符串并在数组中实现所有数据结构一样。

Try 块用于创建在终止时具有一定保证的范围边界(catchfinally 行为)。代码维护者看到:

try{ ... }catch(Exception x){} 

会非常强烈地倾向于重新抛出 x (可能被包装)或完全消除该块。

Try 块与其作用域内的内容无关。这就是标准循环构造以及更好的函数的用途。如果您将范围放在函数中,您的问题就会消失:

RetVal doStuff(Arg arg){
    //--do stuff----
    if(//-------is condition met?--------//)
        return myResult;
}

I'm going to answer the "is is a good idea?" part of the question: No.

It is not a good idea to use exceptions to implement expected flow-of-control. It is possible, but not expected, just as it's possible to make all your variables Strings and implement all your data structures in arrays.

Try-blocks are for creating a scope boundary that has certain guarantees at termination (the catch and finally behavior). A code maintainer seeing:

try{ ... }catch(Exception x){} 

would very strongly tend to either rethrow x (perhaps wrapped) or eliminate the block entirely.

Try-blocks are not about what's inside their scope. That's what standard looping constructs and, better, functions are for. Your question simply goes away if you put your scope in a function:

RetVal doStuff(Arg arg){
    //--do stuff----
    if(//-------is condition met?--------//)
        return myResult;
}
泅渡 2025-01-01 08:07:30

这不是你应该担心会被打破的 try-catch。据我所知,您正在寻求按照以下方式做一些事情:

try
{
  // do thing 1

  // do thing 2

  if (!done)
  {
    // do thing 3

    // do thing 4

    if (still not done)
    {
      // do thing 5
    }
  }
} catch (Exception e)
{

}

如果这就是您想要做的事情,那么您可能应该这样做(而不是试图逃离 try-catch)。另一种方法是缩小 try-catch 块以单独包围每个任务。

如果您为您的问题提供更多背景信息,那么可能会提供更好的答案。

It is not the try-catch that you should worry about breaking out of. From what I can tell, you are looking to do something along the lines of:

try
{
  // do thing 1

  // do thing 2

  if (!done)
  {
    // do thing 3

    // do thing 4

    if (still not done)
    {
      // do thing 5
    }
  }
} catch (Exception e)
{

}

If that is what you are trying to do, then that is probably how you should do it (instead of trying to escape from the try-catch). The other way is to shrink your try-catch blocks to surround each task individually.

If you provide more context to your question then it may be possible to provide a better answer.

∞觅青森が 2025-01-01 08:07:30

只需将其余的获取内容放入具有相反条件的 if 块中即可:

//--do stuff----
if (!shouldStop) {
    // continue doing stuff
}

Just put the rest of the fetching into an if block with the inverse condition:

//--do stuff----
if (!shouldStop) {
    // continue doing stuff
}
迷荒 2025-01-01 08:07:30

看看你的代码

int i=0;
    try {
        //--do stuff----
        if(//-------is condition met?--------//)
            i = 1/0; // divide 1 by 0 -- a definite exception
    }
    catch (Exception e) {//---------do nothing---------//}

是否不满足条件?那么你不需要担心使用break,

如果满足条件,肯定会出现异常,并且在catch中处理它(尽管你没有做任何事情)

Looking by your code

int i=0;
    try {
        //--do stuff----
        if(//-------is condition met?--------//)
            i = 1/0; // divide 1 by 0 -- a definite exception
    }
    catch (Exception e) {//---------do nothing---------//}

if the condition is not met? then you dont need to worry about using break, and

if the condition is met, there will be definitely an exception, and it is handled in catch(although you are not doing anything)

星星的軌跡 2025-01-01 08:07:30

如果没有其他方法,您可以使用块标签,

 load:{
      if(test)//skip the remaining load block
         break load;

  }

否则您可以将加载代码重构为不同的方法并提前返回。

If there is no other way you can use a block label

 load:{
      if(test)//skip the remaining load block
         break load;

  }

Otherwise you could refactor the loading code into a different method and return early.

沙与沫 2025-01-01 08:07:30

不要使用异常进行非异常错误处理。这可能是一个命名的反模式。如果是的话,我不知道名字。

下面是抛出异常时跳出循环并且不使用异常处理来执行非异常错误处理的示例:

try
{
  while (... whatever ...)
  {
    ... do something that might throw a BlammoException.
  }
}
catch (BlammoException exception)
{
  ... handle the exception.
}

Do not use exceptions for non-exception error handling. This is likely a named anti-pattern. If so, I don't know the name.

Here is an example of breaking out of a loop when an exception is thrown and not using exception handling to perform non-exception error handling:

try
{
  while (... whatever ...)
  {
    ... do something that might throw a BlammoException.
  }
}
catch (BlammoException exception)
{
  ... handle the exception.
}
简单气质女生网名 2025-01-01 08:07:30

只需抛出您想要捕获的任何异常...

boolean stopLoop = false;
while (!stopLoop) {
    try {
        int key = Integer.parseInt(userInput);
        if (key > cutOff) throw new NumberFormatException();//<--like this
        else {
            System.out.println("Good job, your number didn't suck");
            //do some stuff...
            stopLoop = true;//<--End loop after some stuff
            //some more stuff, or..
            if(nomorestuff)break;//<--exit loop
        }
    catch (NumberFormatException nfe){
        System.err.println("Enter a number less than "+cutOff);
    }
}//end while

Just throw whichever exception you want caught...

boolean stopLoop = false;
while (!stopLoop) {
    try {
        int key = Integer.parseInt(userInput);
        if (key > cutOff) throw new NumberFormatException();//<--like this
        else {
            System.out.println("Good job, your number didn't suck");
            //do some stuff...
            stopLoop = true;//<--End loop after some stuff
            //some more stuff, or..
            if(nomorestuff)break;//<--exit loop
        }
    catch (NumberFormatException nfe){
        System.err.println("Enter a number less than "+cutOff);
    }
}//end while
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文