Java异常-可能会出现异常丢失的情况&finally

finally的两种特性:

  对于没有垃圾回收和析构函数自动调用机制的语言来说,Java中的finally非常重要。它能使程序员保证:

  1、无论异常是否被抛出,finally子句总能被执行。这个特性我们可以用来解决以下问题:Java的异常不允许我们回到异常抛出的地点时,该如何应对?把try块放在循环里,建立了一个“程序继续执行之前必须要达到”的条件。还可以加入一个static类型的计数器之类的装置,使循环在放弃之前能尝试一定的次数,这将使程序的健壮性更上一个台阶。

  2、无论try块发生了什么,内存总能得到释放。但Java有垃圾回收机制,所以内存释放不再是问题,而且Java也没有析构函数可供调用。那么,Java在什么情况下才能用到finally呢?

  当要把除内存之外的资源恢复到它们的初始状态时,就要用带finally子句。这种需要清理的资源包括:已经打开的文件或网络连接,在屏幕上画的图形,甚至是外部世界的某个开关。

可能导致异常丢失的两种情况:

  1、但是如果用某些特殊的方式使用finally子句,会导致异常丢失:

package com.test.exception.lost;

public class VeryImportantException extends Exception{
    public String toString() {
        return "A very important exception!";
    }
}

package com.test.exception.lost;

public class HoHumException extends Exception {
    public String toString() {
        return "A trivial exception";
    }
}

package com.test.exception.lost;

public class LostMessage {
        void f() throws VeryImportantException {
            throw new VeryImportantException();
        }
        void dispose() throws HoHumException {
            throw new HoHumException();
        }
        public static void main(String[] args) {
            try {
                LostMessage lm = new LostMessage();
                try {
                    lm.f();
                } finally {
                    lm.dispose();
                }
            } catch(Exception e) {
                System.out.println(e);
            }
        }
}

  输出中可以看到,VeryImportantException不见了,被finally子句里的HoHumException取代。这是相当严重的缺陷,C++把“前一个一场还没处理完就抛出下一个异常”的情形看成是糟糕的编程错误。也许在Java的未来版本中(此处为JDK1.7)会修正这个问题。

  2、一种更加简单的异常丢失情况是从finally子句中返回:

package com.test.exception.lost;

public class ExceptionSilencer {

    @SuppressWarnings("finally")
    public static void main(String[] args) {
        try {
            throw new RuntimeException();
        } finally {
            return;
        }
    }

}

  如果运行这个程序,就会看到及时抛出了异常,也不会产生任何输出。(这里就不贴运行结果的图了,不会有任何输出信息在控制台)

总结:

  finally对于保证程序的正确性有很大的用处,但是使用过程中要注意避免以下两种会导致异常丢失的情况(起码在JDK1.7是这样的)

  1、在finally子句中抛出异常;

  2、在finally子句中返回(return)。

时间: 2024-11-08 21:54:45

Java异常-可能会出现异常丢失的情况&finally的相关文章

Java深入理解之异常

Java的基本理念是"结构不佳的代码不能运行" 为什么要使用异常? 首先我们可以明确一点就是异常的处理机制可以确保我们程序的健壮性,提高系统可用率 .异常不是程序语法错误,异常,就是在正常语法的代码运行过程中出现如 一楼所说的情况,如果不进行异常处理,那程序直接结束了,之所以捕获异常,是让你可以有发生错误补救的机会. 异常定义:异常情形是指阻止当前方法或者作用域继续执行的问题.在这里一定要明确一点:异常代码某种程度的错误,尽管Java有异常处理机制,但是我们不能以"正常&qu

java基础1:异常

关于Java基础的文章,我觉得写得还可以,以前发在了我其它的博客了,肯定是原创,现在再分享给大家出来. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

java异常处理(父子异常的处理)

我当初学java异常处理的时候,对于父子异常的处理,我记得几句话“子类方法只能抛出父类方法所抛出的异常或者是其子异常,子类构造器必须要抛出父类构造器的异常或者其父异常”.那个时候还不知道子类方法为什么要这样子抛出异常,后来通过学习<Thinking in Java>,我才明白其中的道理,现在我再来温习一下. 一.子类方法只能抛出父类方法的异常或者是其子异常 对于这种限制,主要是因为子类在做向上转型的时候,不能正确地捕获异常 package thinkinginjava; public abst

Java基础语法&lt;十一&gt; 异常 断言 日志 调试

1 处理错误 1.1 异常分类 Error类层次描述了Java运行时系统的内部错误和资源耗尽错误. 设计Java程序时,主要关注Exception层次结构. 由程序错误导致的异常属于RuntimeException ,而程序本身没有问题,但由于像I/O错误这类问题导致的异常属于其他异常. RuntimeException包含下面几种情况: 错误的类型转换 ClassCastException 数组访问越界 ArrayIndexOutOfBoundsException 访问空指针 NullPoin

java的两种异常runtimeException和checkedException

java异常处理机制主要依赖于try,catch,finally,throw,throws五个关键字. try 关键字后紧跟一个花括号括起来的代码块,简称try块.同理:下面的也被称为相应的块. 它里面可置引发异常的代码.catch后对应异常类型和一个代码块,用于表明catch块用于处理这种类型的代码块.后还可以跟一个finally块,finally块用于回收在try块里打开的物理资源,异常机制会保证finally块总被执行.throws关键字主要在方法签名中使用,用于声明该方法可能抛出的异常,

Java中的ExceptionInInitializerError异常及解决方法

当在静态初始化块中出现了异常的时候,JVM会抛出 java.lang.ExceptionInInitializerError异常.如果你了解Java中的静态变量,你会知道它们是在类加载的时候进行初始化的.如果在这个静态变量初始化的过程中出现了异常,那么就会抛出 java.lang.ExceptionInInitializerError异常.任何异常都可能会引发这种情况,比如说,java.lang.ArrayIndexOutOfBound或者java.lang.NullPointerExcepti

JAVA基础篇三(Java,C++中的异常机制)

由于C++和JAVA有很多相似之处,又有很多细微的差别,所以在学习JAVA的过程中对两种语言进行对比学习. 1.C++的异常机制 C++中处理异常的过程是这样的:在执行程序发生异常,可以不在本函数中处理,而是抛出一个错误信息,把它传递给上一级的函数来解决,上一级解决不了,再传给其上一级,由其上一级处理.如此逐级上传,直到最高一级还无法处理的话,运行系统会自动调用系统函数terminate,由它调用abort终止程序.这样的异常处理方法使得异常引发和处理机制分离,而不在同一个函数中处理.这使得底层

Java常见内存溢出异常分析(OutOfMemoryError)

链接地址:http://my.oschina.net/sunchp/blog/369412 1.背景知识 1).JVM体系结构 2).JVM运行时数据区 JVM内存结构的相关可以参考: http://my.oschina.net/sunchp/blog/369707 2.堆溢出(OutOfMemoryError:java heap space) 堆(Heap)是Java存放对象实例的地方. 堆溢出可以分为以下两种情况,这两种情况都会抛出OutOfMemoryError:java heap spa

Java中的常客异常(一)

Java的基本理念是"结构不佳的代码不能运行"!!!!! 大成若缺,其用不弊. 大盈若冲,其用不穷. 在这个世界不可能存在完美的东西,不管完美的思维有多么缜密,细心,我们都不可能考虑所有的因素,这就是所谓的智者千虑必有一失.同样的道理,计算机的世界也是不完美的,异常情况随时都会发生,我们所需要做的就是避免那些能够避免的异常,处理那些不能避免的异常.这里我将记录如何利用异常还程序一个"完美世界". 一.为什么要使用异常 首先我们可以明确一点就是异常的处理机制可以确保我