Java - 在try/catch块内再使用一个try/catch块是一种不好的编程实践吗?

64

我有一些代码,希望在发生异常时执行它。但是这段代码也可能会产生异常。但我从未见过人们在一个try/catch块内再嵌套另一个try/catch块。

我正在做的方式是否不太好,或者有更好的方法来完成这个任务:

 Uri uri = Uri.parse("some url");
 Intent intent = new Intent(Intent.ACTION_VIEW, uri);

 try 
 {
     startActivity(intent);
 } 
 catch (ActivityNotFoundException anfe) 
 {
     // Make some alert to me

     // Now try to redirect them to the web version:
     Uri weburi = Uri.parse("some url");
     try
     {
         Intent webintent = new Intent(Intent.ACTION_VIEW, weburi);
         startActivity(webintent);
     }
     catch ( Exception e )
     {
         // Make some alert to me                        
     }
 }

这似乎有点尴尬。它可能存在问题吗?


4
你可以考虑将catch块中的代码放入其自己的方法中。 - Hunter McMillen
4个回答

51

虽然这样做没问题,但是如果你的异常处理逻辑太复杂,你可能要考虑将其拆分成单独的函数。


11

在编写代码时,尤其是在使用try-catch时,嵌套层级过多是一个不好的实践。所以我建议避免这种情况。

我的建议是,将你的catch逻辑提取到一个方法中(使catch块变得简单),并确保该方法永远不会抛出任何异常:

Uri uri = Uri.parse("some url");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);

try 
{
    startActivity(intent);
} 
catch (ActivityNotFoundException anfe) 
{
    // Make some alert to me

    // Now try to redirect them to the web version:
    Uri weburi = Uri.parse("some url");
    Intent webintent = new Intent(Intent.ACTION_VIEW, weburi);
    silentStartActivity(webintent)
} 

//...

private void silentStartActivity(Intent intent) {
    try
    {
       startActivity(webintent);
    }
    catch ( Exception e )
    {
        // Make some alert to me                     
    }
}

另外,似乎(我可能错了)你正在使用异常来控制程序流程。如果抛出ActivityNotFoundException不是一个异常情况,而是在正常情况下可能发生的情况,请考虑使用标准返回值。


谢谢...为什么你说在try/catch中抛出异常是一种罪过? :) - GeekedOut
2
“这么多层?”我只看到了三层。他catch块中的逻辑并不比try块中的if块更深刻。 - T.J. Crowder
我看到分解问题的困难在于,由于我试图访问外部URL,我不知道如何检查异常是否会发生。 - GeekedOut
@GeekedOut:你可能需要将处理提取到一个函数中。但是请注意Tomasz刚刚添加的有关使用异常来控制程序流程(反模式)的观点,这是一个很好的观点。 - T.J. Crowder
1
@GeekedOut:因为我考虑的是finally块,而不是catch块。从catch中抛出异常没有问题,但从finally中抛出异常是一个可怕的想法,因为如果finally由于异常而被调用,抛出另一个异常将丢弃原始异常。对不起,我已经删除了这部分内容。 - Tomasz Nurkiewicz
显示剩余6条评论

6

答案是否定的,这很正常。在JDBC和IO中,您可能需要使用很多这样的异常处理,因为它们有很多需要处理的异常,其中一个异常可能会嵌套另一个异常...


0

如果您不想使用嵌套的try和catch,这里有一个替代方案,您也可以这样做:

 boolean flag = false;
 void test();
 if(flag)
  {
   test2();
  }

测试方法在这里:

private void test(){
   try {
        Uri uri = Uri.parse("some url");
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
   }catch (ActivityNotFoundException anfe){
        System.out.println(anfe);
        flag =true;
     }
 }

现在将其余的代码放入第二个方法中:

public void test2(){
  Uri weburi = Uri.parse("some url");
        try
        {
           Intent webintent = new Intent(Intent.ACTION_VIEW, weburi);
           startActivity(webintent);
        }
        catch ( Exception e )
        {
            // Make some alert to me                     
        }

6
在Java和许多其他编程语言中,你可以用许多不同的方式编写相同的条件逻辑。问题是,为什么你认为自己的方法比简单地在第一个try/catch的catch块中编写第二个try/catch更好、更有效或更优化。 - Kartik Pandya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接