java之异常处理

[toc]
异常的父类:Throwable
两大子类:Error和Exception
error一旦出现(比如说内存溢出、虚拟机错误、内存死锁等),程序将会崩溃,我们无法解决,主要讨论Exception(也就是通常所说的异常)。异常一般是编码、环境、用户操作输入出现问题。

Exception的子类:RuntimeException(运行时异常,也即非检查异常,其他异常被称为检查异常(CheckException))
引起运行时异常:可能是引用了一个空对象的属性或方法(空指针异常NullPointerException),也有可能是数组访问越界(数组下标越界异常ArrayIndexOutOfBoundsException),或者是错误的类型转换(类型转换异常),又或者是用整数去整除0(算术异常ArithmeticException)
上面括号中的异常全是RuntimeException的子类

运行时异常会由java虚拟机自动抛出并自动捕获,运行时异常的出现绝大部分时候说明了代码本身有问题

引起检查异常:文件不存在(文件异常IOException)、数据库连接问题(SQL异常SQLException)
需要手动添加捕获以及处理语

一般使用try…catch…finally实现异常处理
try{
    //一些会抛出异常的方法
}catch(Exception e){
    //处理该异常的代码块
}finally{
    //最终将要执行的一些代码,比如说关闭链接
}

例如下面这个例子就可以判断输入类型是否为整数

try{
    System.out.println("请输入你的年龄);
    Scanner input = new Scanner(System.in);
    int age = input.nextInt();
    system.out.println("十年后你" + (age+10) + "");

}catch(InputMismatchException e){
    System.out.println("你应该输入整数!")
}

若try中的方法会抛出很多种类型的异常,则写多个catch方法(跟在catch后面的括号里的异常类型要改变)
在写catch语句块时,要根据异常的类型先写子类后写父类。原因是出现异常时会就近寻找匹配的异常处理程序,而针对于父类的异常处理程序对于子类也是适用的。
就比如最后的catch语句可以写成:

catch(Exception e)
{
    System.out.println("我是不知名异常");
}

e.printStackTrace();可以打印异常的具体信息
其他:
1.try 语句块后catch语句块和finally语句块至少要有一个。
2.无论是否发生异常,finally语句块都会被执行。即使catch中有return语句,也要先执行完finally语句块再return。
3.try, catch, finally之间不能插入其他语句。
4.尽量添加finally语句去释放占用的资源

关于后续语句

1.如果try语句块没有发生异常,后续语句会被执行;
2.如果try语句块发生了异常,但没有被捕获,则后续语句不会执行;
3.如果捕获了异常,且相应catch语句块中没有return语句,则后续语句会被执行,有return语句则后续语句不会执行。
4.因为finally语句块总是会被执行的,所以如果finally语句块中有return语句,就不能有后续语句。原因是后续语句不可能被执行到。
5.Try语句块中的return语句如果执行了,后续语句也不会执行。
6.如果finally语句块中有return,则执行的总是finally中的return。

java中的异常抛出

throws-声明将要抛出任何种类型的异常(是声明)

public void 方法名(参数列表)
    throws 异常列表{
    //调用会抛出异常的方法或者throw new Exception();
}

1.可抛出多种类型异常,每个异常中间用分号隔开即可
2.子类方法若要覆盖父类方法,且父类方法中声明了throws异常,则子类的方法也可以throws异常(只能throws 更具体的异常,不能throws更一般的异常)

throw-写在方法体里,将产生的异常抛出(是动作)
例如:

if (divider == 0)
    throw new Exception("除数不能为0!")
而若某方法调用了含有这个if语句的方法 则需要使用try catch语句处理异常
如:try
{
    divide(5,0);
}
catch(Exception e){
    System.out.println(e.getMessage());
}

或throws抛出给更上一层

自定义异常
class 自定义异常类(aException) extends 异常类型{
//无参构造
    public aException(){}
//含参构造
    public aException(String s)
    {
        super(s);
    }
}
/*
其实除了传入message之外,也是支持传入原因的
public class myException extends Exception{
    public myException(String message,Exception cause)
    {
        super(message,cause);
    }
}
*/
异常链

若test1()会抛出一个自定义异常DrunkException
则可以

try{
    test1();
}catch(DrunkException e){
    RuntimeException newExc = new RuntimeException("巴拉巴拉巴拉");
    newExc.initCause(e);
    //以上两句也可以直接写为RuntimeException newExc = new RuntimeException(e);
    throw newExc;
}

然后main就要处理RuntimeException

try-with-resource
try(类型 变量名 = new 类型()){
    ……
    //自动添加finally{变量.close()} 无论是否出现异常都会执行
}
//使用try-catch-finally
BufferedReader br = new BufferedReader(new FileReader(path));
      try {
        return br.readLine();
      } finally {
        if (br != null) br.close();
      }
//使用try-with-resource
 try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        return br.readLine();
      }

使用第一种方式如果 readLine 和 close 方法均抛出异常,那么方法将抛出从 finally 块中抛出的异常; try 块中抛出的异常被抑制了。与此相反, 在 后一种例子中, 如果 try 块和 try-with-resource 语句均抛出异常, 那么 方法将抛出从 try 块中抛出的异常;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值