class VeryImportantException extends Exception{
 private static final long serialVersionUID = 1L;
 public String toString(){
  return "very important";
 }
}class ImportantException extends Exception{
 private static final long serialVersionUID = 1L;
 public String toString(){
  return "important";
 }
}public class LostMessage {
 public void f() throws VeryImportantException{
  throw new VeryImportantException();
 }
 public void g() throws ImportantException{
  throw new ImportantException();
 }
 public static void main(String[] args) throws Exception {
 LostMessage lm=new LostMessage();
       try{
       lm.f();
       } 
       finally{
       lm.g();
       } }}
 结果为:Exception in thread "main" important
 at LostMessage.g(LostMessage.java:33)
 at LostMessage.main(LostMessage.java:41)
 把f()的异常给屏蔽了,因为finally()中的g()

解决方案 »

  1.   

    但是,如果这样调用,就会出现bug,要和不要是一回事,不能正常处理是另外一回事,不能保证finally中函数,就一定没有异常,比如文件的close()
      

  2.   

    这不应该算是 Java 的 BUG,在 Java Language Specification 中对 try-catch-finnal 的 exception 处理流程有严格、完整的定义。一个 method 不能同时抛两个 Exception 出来,丢掉一个是必然的,你可以通过适当的代码选择保留哪个。被忽略的那个应该被理解为“已经处理过了”。
      

  3.   

    C++指出,如果第一个异常处理结束之前就处理第二个异常,是严重的疏忽
    连Think in java作者,也认为这是个问题,不信你去看看,我刚看到
      

  4.   

    还有,如果你把Think in java 当成经典,那好,这个bug是Bruce Eckel提出的,不是我提出的,我只是看他说新版本java会改进,但1.5还没有改而已,别把矛头指向我,谢谢
      

  5.   

    在使用时,我一般是把finally的异常内部处理掉,因为finally里面一般是释放资源,例如连接了,关闭文件了之类的,所以在finally里面我就知道如何处理了,不用把异常抛出到上一层中。至于说在这一层没有办法处理,而必须抛出的情况,确实是个问题。
      

  6.   

    楼主已经连续 up 三次了,我来接一下吧  :)楼主认为在这种情况下,作为 Java 语言的语法应该如何处理才好呢?如果能提出好的建议,让 Sun 在下一版 Java 中做修改也不是不可能啊。
      

  7.   

    谢谢楼上的,我觉得应该不忽略掉,这样会让人觉得没有exception产生而忽视。--胡想的
      

  8.   

    这种情况下,你也可以认为是Java 的一个Bug。但是一般情况下,最好做到finally 块中不要抛出Exception,或者抛出后直接捕获抛弃。因为一般认为,在try 块中抛出的Exception 才是我们想要的
      

  9.   

    不认为是 bug。
    不能将一切都依赖于语言,实际上,
    try{
      throw new Exception();
    }finally{
      return;
    }
    这样也会导致异常消失。记得以前看过一篇文章,
    continue, break, return, throw exception
    是属于 同一类的程序流的跳转,
    任何最新出现的 跳转 都会覆盖 之前出现的。
    比如上面这里,在 finally 中,有一个 throw excpetion 的跳转,
    但被最新的 return 所覆盖了,导致其中的 exception 消失了。
    楼主的情况就是新的 exception 覆盖了旧的。还可以再试这些:
    for(int i=0; i<1; i++){
      try{
        throw new Exception();
      }finally{
        continue;
      }
    }for(;;){
      try{
        throw new Exception();
      }finally{
        break;
      }
    }同样发现异常神奇地消失了。
      

  10.   

    <<个人理解>>不是Bug!
    原则上,程序碰到异常就退出去了。所以只有一个异常能显示出来。
    但是,“finally”是一定执行的。它里面又出现了异常。结束。
    且异常信息在堆栈中一定靠上。所以输出finally里的那个异常信息。
      

  11.   

    哪是什么bug自己的编程思想和习惯有问题了
      

  12.   

    楼上的,如果我问你对thinking in java怎么看,你肯定说--经典
    如果我再跟你说,这问题是作者提出的,你还会说“自己的编程思想和习惯有问题了”吗?我看不会,哎,我就不说什么了
      

  13.   

    <java puzzlers>已经有讨论,不算bug