【问题标题】:Handle exception in the called method/function Java/Android?在被调用的方法/函数 Java/Android 中处理异常?
【发布时间】:2017-12-13 10:23:22
【问题描述】:

我得到了这个方法:

public void foo(){
    int test = 5/0;
}

我这样称呼它:

try {
    foo();
} catch (Exception e){
    e.printStackTrace();
}

这会捕获ArithmeticException,但我见过我在try-catch 中调用方法的情况,但它没有捕获异常。有没有exception可能抓不到的具体情况?

这是一个澄清问题的例子: ActivityA 中的 try-catch 块是否捕获了 ActivityB 中的异常?我知道答案是否定的。但我想知道这背后的逻辑。

public class ActivityA extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        try {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_a);
            startActivity(new Intent(this, ActivityB.class));
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

还有ActivityB:

public class ActivityB extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_b);
        int x = 5/0    
    }
}

对于所有认为这是一个重复问题的酷人,请给我一个 StackOverFlow 上的问题的链接,该问题回答了这个非常明确的问题:try-catch 是否捕获在其内部调用的方法中发生的异常?

【问题讨论】:

标签: java exception try-catch


【解决方案1】:

可能发生的情况是您试图捕获一个不是被触发的异常。 在ArithmeticException 的情况下,如果你触发了一个,例如NumberFormatException,它不会持有Exception 并且会停止你的应用程序。

【讨论】:

    【解决方案2】:

    如果你捕获了ExceptionException 本身以及所有属于Exception 子类型的异常都将被该块捕获。在 Java 中,这就是所谓的“检查异常”。

    但是,您不会捕获那些只是Throwable 子类型的“异常”。准确地说,这些并不是真正的例外。它们是错误的。也可以在 try-catch 语句中捕获它们。

    并不是说捕捉ExceptionThrowable 都不是一个好习惯。始终捕获您预期的特定异常和错误。

    【讨论】:

    • 所以如果我在 try-catch 中调用一个方法,然后又调用另一个方法,我可以说 try-catch 捕获所有异常,即使它发生在最远的调用方法中?
    • @saraX 基本上是的。它从try 块内的所有调用中捕获异常。如果未捕获到异常,则将其抛出调用层次结构,直到在某处被捕获(如果未在任何地方捕获,则程序崩溃)。
    • 所以如果我将所有代码放在我的onCreate() 方法中,它会捕获我的应用程序中的所有异常,因为它是我的应用程序的起点,并且所有其他东西都是从它内部调用的?跨度>
    • @saraX 如果没有事先发现:是的
    【解决方案3】:

    如果您指定要捕获的异常,例如

    public void foo(numb, divisor) throws ArithmeticException {
        if (divisor == 0) throw new ArithmeticException();
        int ans = num / divisor;
    }
    
    @Test
    public void tesfooWithZeroDivisor() {
        try {
            foo(5, 0);
        } catch (ArithmeticException e) {
            System.out.println("Can't divide by zero");
        }
    
    }
    

    在这种情况下,您指定要在抛出 ArithmeticException 时被捕获。如果没有抛出 ArithmeticException 而是抛出 IllegalArgumentException 等不同的异常,则它不会捕获 IllegalArgumentException,因为您只指定了 ArithmeticException。

    在您的情况下,您使用了catch (Exception e),这意味着您没有指定异常,因此它会捕获任何抛出的异常。

    【讨论】:

      【解决方案4】:

      是否有特定情况可能无法捕获异常?

      脑海中浮现出一些情况:

      • 代码(例如对foo()的调用)未执行。所以没有抛出异常。
      • 异常是由不同的代码引发的;例如在您的示例中,foo() 方法是从其他地方调用的;例如在不同的线程堆栈上。
      • 异常被进一步捕获到调用链中。
      • 您已经声明了自己的异常(例如my.pkg.ArithmeticException),并且您正在捕获与作为结果引发的异常不同的异常
      • 如果您使用类加载器做一些奇怪的事情,则可以多次加载同一个类。如果这样做,您将拥有名称相同但实际上不同的类型。如果您使用异常类执行此操作,则处理程序执行的 instanceof 测试可能无法匹配。

      try-catch 是否捕获在其内部调用的方法中发生的异常?

      是的。如果您已正确实施;见上文。

      如果你想要章节和诗句,请阅读JLS 14.20


      关于您更新的示例,我不希望ActivityA 的异常处理程序看到ActivityB.onCreate 中抛出的异常。我希望 onCreate() 被不同的线程调用。

      您可以通过在ActivityB.onCreate 中捕获异常并查看堆栈跟踪来确认这一点。

      【讨论】:

      • 根据答案之一,如果我将所有代码放在我的onCreate()method 中,它会捕获我的应用程序中的所有异常,因为它是我的应用程序的起点,所有其他的东西都是从在里面。是的?如果我对 try-catch 块内的另一个活动使用意图怎么办?这是否意味着新的Activity 中的所有异常都被捕获了? @斯蒂芬-c
      • 给我们一个具体的例子。但总的来说,答案是否定的。事实上,代码在您的onCreate() 的词汇“内部”并不一定意味着它将由调用您的onCreate() 方法的线程执行。有各种方法可以让代码在 Android 的不同堆栈上运行。
      • 好吧,我编辑了问题并添加了一些代码块给你一个具体的例子。如果您能指导我完成此操作,我将不胜感激。 @斯蒂芬-c
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-21
      • 2020-12-26
      • 2020-09-28
      • 2019-07-25
      • 2021-11-11
      • 2020-04-25
      相关资源
      最近更新 更多