异常处理
来源:互联网 发布:it资产管理系统 php 编辑:程序博客网 时间:2024/06/05 05:32
1异常类的继承
1.try块里声明的变量是代码块内部局部变量,它只在try块内有效,在catch块中不能访问该变量。
2.异常(Exception)和错误(Error)两种,Exception可以被捕获,而Error错误,一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,动态链接失败等,这种错误无法捕获或无法恢复,故catcha是不能捕获到Error对象,也无须在其throws子句中声明该方法可能抛出Error及其任何子类,异常的继承图:
3.进行异常捕获时不仅应该把Exception类对应的catch块放在最后,而且所有的父类异常的catch块都应该排在子类异常catch块的后面(遵循先处理小异常,再处理大 异常)
4.捕获多种类型的异常时,多中异常类型之间用竖线(|)隔开,异常变量有隐式的final修饰,因此程序不能对异常变量重新赋值
代码例子:
public class MultiExceptionTest{ public static void main(String[] args) { try { int a = Integer.parseInt(args[0]); int b = Integer.parseInt(args[1]); int c = a / b; System.out.println("您输入的两个数相除的结果是:" + c ); } catch (IndexOutOfBoundsException|NumberFormatException |ArithmeticException ie) { System.out.println("程序发生了数组越界、数字格式异常、算术异常之一"); // 捕捉多异常时,异常变量默认有final修饰, // 所以下面代码有错: ie = new ArithmeticException("test"); //① } catch (Exception e) { System.out.println("未知异常"); // 捕捉一个类型的异常时,异常变量没有final修饰 // 所以下面代码完全正确。 e = new RuntimeException("test"); //② } }}
5.异常处理语法结构中只有try块是必需,而catch和finally是可选的(但必需catch和finally块至少出现其中之一),catch如果有return语句,在执行return语句之前,程序还会执行finally块,但如果catch如果有System.exit(1)语句,则不会执行finally块。
代码例子:
public class FinallyTest{ public static void main(String[] args) { FileInputStream fis = null; try { fis = new FileInputStream("a.txt"); } catch (IOException ioe) { System.out.println(ioe.getMessage()); //return语句强制方法返回,会执行下面的finally return ; //① //使用exit来退出虚拟机,不会执行下面的finally //System.exit(1); //② } finally { //关闭磁盘文件,回收资源 if (fis != null) { try { fis.close(); } catch (IOException ioe) { ioe.printStackTrace(); } } System.out.println("执行finally块里的资源回收!"); } }}
6.不要在finally块中使用如return或throw等导致方法终止的语句,一旦在finally快中使用了return或throw语句,将会导致try块,catch块中的return,throw语句失效。
代码例子:
public class FinallyFlowTest{ public static void main(String[] args) throws Exception { boolean a = test(); System.out.println(a); } public static boolean test() { try { // 因为finally块中包含了return语句 // 所以下面的return语句失去作用 return true; } finally { return false; } }}
7.java7以后,允许try关键字后紧跟一对圆括号(这里try语句相当于包含了隐式的finally,所以后面不需要有catch和finally块),圆括号里可以声明,初始化一个或多个资源,此处的资源指的是那些必须在程序结束时显示关闭的资源(比如数据库连接,网络连接),try语句在该语句结束时会自动关闭这些资源(这些资源实现类必须实现AutoCloseable或Closeable接口)
代码例子:
public class AutoCloseTest{ public static void main(String[] args) throws IOException { try ( // 声明、初始化两个可关闭的资源 // try语句会自动关闭这两个资源。 BufferedReader br = new BufferedReader( new FileReader("AutoCloseTest.java")); PrintStream ps = new PrintStream(new FileOutputStream("a.txt"))) { // 使用两个资源 System.out.println(br.readLine()); ps.println("庄生晓梦迷蝴蝶"); } }}
2Checked异常和Runtime异常体系
1.Checked异常需要程序显示处理(一般是通过try…catch),否则程序会产生编译错误,而Runtime异常则不要程序显示处理。
代码例子:
public class Test{ public static void g() throws RuntimeException { String a=null; } public static void t() throws Exception { String a=null; } public static void main(String[] args) { //编译通过,因为异常是UnChecked类型 g(); //编译不通过,因为异常是Checked类型 //要么用try,要么用throws,编译才能通过 t(); }}
3使用throw抛出异常
1.throw语句常用于catch代码快中,其抛出的不是异常类,而是异常实例,且只能抛出一个异常实例。
2用户自定义异常都应该继承Exception基类,如果希望自定义Runtime异常,则应该继承RuntimeException基类,一般需要提供两个构造器:一个是无参数的构造器,另一个是带一个字符串参数的构造器。
代码例子:
public class AuctionException extends Exception{ //无参数的构造器 public AuctionException(){} //① //带一个字符串参数的构造器 public AuctionException(String msg) //② { super(msg); }}
3.java7以后,Java编译器会执行更细致的检查,Java编译器会检查throw语句抛出异常的实际类型
代码例子:
public class ThrowTest2{ public static void main(String[] args) // Java 6认为①号代码可能抛出Exception, // 所以此处声明抛出Exception// throws Exception // Java 7会检查①号代码可能抛出异常的实际类型, // 因此此处只需声明抛出FileNotFoundException即可。 throws FileNotFoundException { try { new FileOutputStream("a.txt"); } catch (Exception ex) { ex.printStackTrace(); throw ex; //① } }}
4.捕获一个异常然后接着抛出另一个异常,并把原始信息保存下来,这种典型的链式处理被称为“异常链”,JDK1.4以后,所有Throwable的子类在构造器中都可以接受一个cause对象作为参数,而这个cause就来表示原始异常。
代码例子:
第一种不使用异常链处理:
public class Test{ public static void g() { try { String a=null; System.out.println(a.length()); } catch (Exception e) { throw new RuntimeException(); } } public static void main(String[] args) { System.out.println("g()方法异常信息"); g(); }}
运行结果:
**g()方法异常信息
Exception in thread main java.lang.RuntimeException**
第二种使用异常链处理:
public class Test{ public static void t() { try { String a=null; System.out.println(a.length()); } catch (Exception e) { throw new RuntimeException(e); } } public static void main(String[] args) { System.out.println("t()方法异常信息"); t(); }}
运行结果:
**Exception in thread main java.lang.RuntimeException: java.lang.NullPointerException
Caused by: java.lang.NullPointerException**
比较这两种的运行结果了,可以看出,异常链式处理打印出了最原始的异常信息,而非异常链式处理只打印最后一个抛出的异常信息。
4Java的异常跟踪栈
1. 异常的传播规则:只要异常没有被完全捕获(包括异常没有被捕获,或异常被处理后重新抛出了新异常),异常从发生异常的方法逐渐向外传播,首先传给该方法的调用者,该方法调用者再次传给其调用者…….
代码例子:
class SelfException extends RuntimeException{ SelfException(){} SelfException(String msg) { super(msg); }}public class PrintStackTraceTest{ public static void main(String[] args) { firstMethod(); } public static void firstMethod() { secondMethod(); } public static void secondMethod() { thirdMethod(); } public static void thirdMethod() { throw new SelfException("自定义异常信息"); }}
运行结果:
**Exception in thread ‘main’ csdn1.SelfException: 自定义异常信息
at csdn1.PrintStackTraceTest.thirdMethod(PrintStackTraceTest.java:27)
at csdn1.PrintStackTraceTest.secondMethod(PrintStackTraceTest.java:23)
at csdn1.PrintStackTraceTest.firstMethod(PrintStackTraceTest.java:19)
at csdn1.PrintStackTraceTest.main(PrintStackTraceTest.java:15)**
这篇博客参考资料
Java疯狂讲义2
- 异常处理+异常+处理异常+自定义异常
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 异常处理
- 循环-03. 求符合给定条件的整数集(15)
- Eclipse打包Android混淆代码降低代码可读性时,出现的Warning:can't find referenced class问题的解决方案
- Linux下retext无法实时预览
- 模仿快递打车倒计时
- 向量
- 异常处理
- 使用git从openshift克隆应用报错
- 黑马程序员——反射
- Leetcode:Add Two Numbers
- Redis和Memcached的区别
- Linux内核分析(六)----字符设备控制方法实现|揭秘系统调用本质
- [Usaco2009 Jan]安全路经Travel(最短路树+并查集/树链剖分)
- Linux内核分析(五)----字符设备驱动实现
- 【Win7 服务优化pc版】