美文网首页
从0开始复习Java(7)--Exception

从0开始复习Java(7)--Exception

作者: ifeelok0319 | 来源:发表于2017-04-26 21:11 被阅读22次

Java将异常分为两类:Checked异常和Runtime异常。Java认为前者都是可以在编译阶段被处理的异常,所以它强制程序处理所有的Checked异常;而Runtime异常则无需处理。

一、异常概述

try{
    //业务实现代码
}
catch (Exception e){
}
finally {
}

try块里面的业务逻辑代码出现异常,则系统自动生成一个异常对象,该异常对象被提交给Java运行时环境,这个过程成为抛出(throw)异常。Java运行时环境去寻找处理该异常对象的catch块,找到合适的则把该异常对象交给该块处理,成为捕获(catch)异常;找不到则运行时环境终止。

try块后面的花括号不能省略,它定义的变量在catch块中不能访问。catch也不能省略花括号。

Java异常类继承关系Java异常类继承关系

二、异常处理机制

多异常捕获

Java7开始,一个catch可以捕获多种类型的异常。需要注意:

  • 多种异常类型之间用竖线隔开
  • 异常变量有隐式的final修饰,程序不能对异常变量重新赋值。
public class Test{
    public static void main(String[] args) {
        try{
            int a = Integer.parseInt(args[0]);
            int b = Integer.parseInt(args[1]);
            int c = a/b;
        }
        catch (IndexOutOfBoundsException|NumberFormatException|ArithmeticException e){
            //下面报错
            e = new ArithmeticException("test");
        }
        catch (Exception e){
            e = new RuntimeException("test");
        }
    }
}

访问异常信息

  • getMessage()
  • printStackTrace()
  • printStackTrace(PrintStream s)
  • getStackTrace()

使用finally回收资源

Java回收机制不会回收物理资源,只能回收对内存中对象所占用的内存。

即使是try或者catch语句里面有return语句,finally块也会执行。

异常处理语法结构中只有try块是必须的,catchfinally块至少出现一个,也可以同时出现。

import java.io.FileInputStream;
import java.io.IOException;

public class Test{
    public static void main(String[] args) {
        FileInputStream fis = null;
        try{
            fis = new FileInputStream("a.txt");
        }
        catch(IOException e){
            System.out.println(e.getMessage());
            //下面方法继续执行finally
            //return;
            //下面方法退出虚拟机,不会执行finally
            //System.exit(1);
        }
        finally{
            if(fis!=null){
                try{
                    fis.close();
                }
                catch(IOException e){
                    System.out.println(e.getMessage());
                }
            }
        }
    }
}

一旦在finally块中使用throwreturn语句,trycatch语句中的相应语句将会失效。

自动关闭资源的try语句

Java7开始,允许将那些必须在程序结束时显式关闭的资源放在try后面的圆括号里面。

这些资源实现类必须实现AutoCloseableCloseable接口,这两个接口有close方法。

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.PrintStream;

public class Test{
    public static void main(String[] args) {
        try(
            BufferedReader br = new BufferedReader(new FileReader("test.txt"));
            PrintStream ps = new PrintStream(new FileOutputStream("a.txt"));
        ){
            ps.println("this is nothing");
        }
    }
}

Java7几乎把所有的资源类进行了改写,都实现了AutoCloseableCloseable接口

三、Checked异常和Runtime异常

所有RuntimeException类及其子类的实例被称为Runtime异常,其他的被称为Checked异常。

Checked异常体现了Java的设计哲学--没有完善错误处理的代码根本就不会被执行。该类异常的处理方式:

  • 当前方法明确知道该怎么处理,try,catch
  • 当前方法不知道该怎么处理,应该在定义该方法时抛出该异常

使用throws声明抛出异常

如果main方法也不知道怎么处理异常,则交给jvm处理。jvm打印异常的跟踪栈信息,并终止程序运行。

throws ExceptionClass1, ExceptionClass2...

子类方法声明抛出的异常应该是父类方法声明抛出的异常类型的子类或相同,子类方法声明的异常不允许比父类方法声明抛出的异常多。

在大部分时候推荐使用Runtime异常

四、使用throw抛出异常

throw语句抛出的不是异常类,而是异常实例,而且每次只能抛出一个异常实例。

throw ExceptionInstance;

规则:

  1. throw语句抛出的是Checked异常,该throw语句要么处于try块里,显式捕获该异常,要么放在一个带throws声明抛出的方法中,把该异常交给该方法的调用者处理
  2. throw语句抛出的是Runtime异常,则该语句无需放在try块里,也无需放在throws方法中;
  3. 程序既可以显式使用try...catch捕获并处理该异常,也可以完全不理会,把该异常交给该方法的调用者。

自定义异常类

用户自定义异常应该继承Exception类。

通常需要实现两个构造器,如下:

public class AuctionException extends Exception{
    public AuctionException(){}
    public AuctionException(String msg){
        super(msg);
    }
}

catch和throw同时使用

在实际应用中往往需要更复杂的处理方式:
当一个异常出现时,必须由几个方法协作才能完全处理该异常。

异常链

自定义异常类需要多实现一个方法。

public class TestException extends Exception{
    public TestException(){}
    public TestException(String msg){
        super(msg);
    }
    public TestException(Throwable t){
        super(t);
    }
}

五、Java的异常跟踪栈

六、异常处理规则

  • 使程序代码混乱最小化
  • 捕获并保留诊断信息
  • 通知合适的人员
  • 采用合适的方式结束异常活动

不要过度使用异常

对于普通的错误,应该编写处理错误的代码,对于外部的、不能确定和预知的运行时错误才使用异常。

避免过大的try语句

避免使用catchAll语句

不要忽略捕获到的异常

  • 处理异常
  • 重新抛出异常
  • 在合适的层处理异常

相关文章

  • 从0开始复习Java(7)--Exception

    Java将异常分为两类:Checked异常和Runtime异常。Java认为前者都是可以在编译阶段被处理的异常,所...

  • 从0开始复习java(1)

    java语言概述 1、java8的新特性。 重新设计的接口语法,Lambda表达式,方法引用,构造器引用,函数式编...

  • 从0开始复习java(2)

    面向对象 1、方法的参数传递机制 java里方法的参数传递方式只有一种:值传递。 2、方法的所属性 方法不能独立定...

  • 从0开始复习Java(10)

    一、线程概述 进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位。 进...

  • 从0开始复习java(3)

    一、面向对象 1、包装类 java5之后有自动装箱和自动拆箱功能。 包装类可以实现基本类型变量和字符串之间的转换。...

  • 从0开始复习java(5)--Collection

    Java 集合类是一种特别有用的工具类,大致可分为Set、List、Queue、Map四种体系。 Set代表无序、...

  • 从0开始复习Java(8)--Annotation

    Java5增加了对MetaData的支持,也就是Annotation。这些标记在编译、类加载、运行时被读取,并执行...

  • 从0开始复习java(4)--Class

    oracle为java提供了丰富的类库,java8提供了4000多个基础类。java程序员至少要熟悉java中70...

  • 从0开始复习java(9)--IO

    Java的io通过java.io包下的类和接口支持。主要有输入、输出流,又分为字节流和字符流。Java的io流使用...

  • 从0开始复习java(6)--GenericType

    Java5增加泛型支持在很大程度上都是为了让集合能记住其元素的数据类型。在没有泛型之前,一旦把一个对象放进集合中,...

网友评论

      本文标题:从0开始复习Java(7)--Exception

      本文链接:https://www.haomeiwen.com/subject/jvuwzttx.html