一道面试题,关于java的异常处理的

class Annoyance extends Exception {}
class Sneeze extends Annoyance {}

class Human {

    public static void main(String[] args) 
        throws Exception {
        try {
            try {
                throw new Sneeze();
            } 
            catch ( Annoyance a ) {
                System.out.println("Caught Annoyance");
                throw a;
            }
        } 
        catch ( Sneeze s ) {
            System.out.println("Caught Sneeze");
            return ;
        }
        finally {
            System.out.println("Hello World!");
        }
    }
}

下面公布输出结果以及我的问题,如果没遇到这个问题的可以先想想输出结果是什么












请输入代码

输出
Caught Annoyance
Caught Sneeze
Hello World!
我的思路是这样的,首先抛出 throw new Sneeze();被它的父类Annoyance的catch块接受到,打印Caught Annoyance
接着抛出父类Annoyance对象,该对象不能被子类接受到吧,所以应该是捕捉不到,但是程序运行的结果还是捕捉到了并打印Caught Sneeze。
这是为什么呢?

阅读 5.3k
4 个回答

throw new Sneeze();

为何不能被?

} catch (Sneeze s) {
  System.out.println("Caught Sneeze");
  return;
}

你对Java的类这个概念了解还不够,Sneeze是Annoyance的子类,意味着Sneeze一定是Annoyance,所以参数类型为Annoyance的时候,传递进去一个Sneeze实例并没有什么问题,这个实例在被抛出的时候当然会被捕获。有一段类似的代码你可以看看。

class Animal  {
    void talk(){
        System.out.print("I'm Animal");
    }
}
class Human extends Animal {
    void talk(){
        System.out.print("I'm Human");
    }
}

class Main{
    public static void main(String[] args) throws Exception {
        bark(new Human());
    }

    static void bark(Animal a){
        a.talk();
    }
}

在上面的代码中,为什么最后会打印I'm Human而不是I'm Animal

这里没有做任何的类型转换,打印Caught Annoyance之后抛出的仍然是之前的对象,只是由父类型引用了。
你描述的情况是下面的情形:

public class Human {
    public static void main(String[] args) throws Exception {
        try {
            try {
                throw new Sneeze();
            } catch (Annoyance a) {
                System.out.println("Caught Annoyance");
                throw new Annoyance();
            }
        } catch (Sneeze s) {
            System.out.println("Caught Sneeze");
            return;
        } finally {
            System.out.println("Hello World!");
        }
    }
}

这个应该是下转型的问题

题主的问题简化成下面的样子会清晰点

Annoyance a=new Sneeze();
Sneeze s=(Sneeze)a;
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题