JAVA高级应用之异常类处理

异常分类

Throwable(异常最顶端的类)
    Error(服务器奔溃 数据库奔溃)
    Exception(异常类)
        RunTimeException

解决异常

1.出现异常 找上级去解决
2.找上级去解决 相当于找任务的调用者 mian的调用者 JVM去处理
3.JVM默认的处理方式
        打印异常类 错误信息 和 错误发生的位置
        直接停止程序

代码示例

public class Demo01{
    public static void main(String[] args){
        int[] array = new int[3];
        // 角标越界异常 ArrayIndexOutOfBoundsException
        System.out.println(array[6]);
        // 空指针异常 NullPointException
        array = null;
        System.out.println(array.length);
        // 算术异常 ArithmeticException
        System.out.println(10/0);
    }
}

写法

try....catch....finally
try 指测试异常代码
catch 指捕获异常信息
finally 指异常结束后要做的事

处理异常的流程

1.函数中 某句代码发生异常
2.发生异常 会产生对应的异常对象
3.这个异常对象 返回给调用者
        情况1:没有对异常进行处理 这时就会把异常交给上级
              交给JVM去处理 JVM使用了默认的处理机制
        情况2:调用者进行了异常处理(try....catch) 这时返回的
              异常对象 会跟catch进行匹配 匹配成功执行catch中的语句
              程序继续执行

代码示例

public class Demo02{
    public static void main(String[] args){
        Fun test = new Fun();

        try{
            int num = test.fun(10,0);
            System.out.println(num);
        }catch(ArithmeticException e){ // 小括号中要放捕获什么异常
            System.out.println("除数不能为0");
        }
        System.out.println("你猜猜我执行了吗");
    }
}

class Fun{
// 发生异常 一定会产生一个对应的异常对象
    public void fun(int a, int b){
    // new ArithmeticException("/ by zero")
        return a/b;
    }
}

结果

除数不能为0
你猜猜我执行了吗

多catch处理异常

public class Demo03{
    public static void main(String[] args){
        int[] array = new int[4];
        try{
            // 报的越界异常 产生了越界异常的对象
            // new ArrayIndexOutOfBoundsException("5");
            System.out.println(array[5]);
            array = null;
            // 报的空指针异常 产生了空指针异常对象
            // new NullPointException()
            System.out.println(arr.length);
            // 10/0 报运算异常
            // new ArithmeticException()
            System.out.println(10/0);
        }catch(ArrayIndexOutOfBoundsException e){
            System.out.println("下标不能越界");
        }catch(NullPointException e){
            System.out.println("空指针异常 ");
        }catch(ArithmeticException e){
            System.out.println("出现算术错误 你除0了");
        }   
        System.out.println(你猜猜我运行了吗);
    }
}

结果分析

每当出现异常时 便会返回一个异常对象,与catch中的引用进行比对 ,遇到相应的引用,
便会执行其中的语句,其余的catch不会执行,之后会打印"你猜猜我运行了吗"

Finally

finally(遗言)
出现异常与否不会影响到finally的执行
也就是说finally一定会执行
finally作用:一般用来关闭资源 关闭流 关闭数据库

final finally finalize 的区别? 雷锋和雷峰塔的区别
final(绝育)
finally(遗言) 异常处理时候使用 不能单独使用
finalize() 是个方法 是做垃圾回收的时候用 系统自己调用

安卓开发
客户端开发 直接使用Exception e 来接收异常

JavaEE开发
服务器开发 一般会把异常 记录下来 写成错误日志 回头查看
如果不记录 相当于把这个错误遗漏过去

代码示例

public class Demo04{
    public static void main(String[] args){

    try{
        System.out.println(10/0);
        // 即使你直接return方法 finally也会执行
        // 直接关闭JVM 虚拟机关了 就不执行了
        return;
        // System.exit(0);
    }catch(Exception e){
        System.out.println("不能除以0");
    }finally{
        System.out.println("我要工资破万");
    }
    System.out.println("你猜猜我执行了吗");
}

输出结果

不能除以0
我要工资破万
你猜猜我执行了吗

代码示例

class TestFinally{
    public int fun(){
        int num = 10;
        try{
            num = 20;
            System.out.println(11/0);
            return num;
        }catch(Exception){
            num = 30;
            return num;
        }finally{
            num = 40;
            // finally中只写关闭资源 在这里添加return没有意义
        }

    }
}

输出结果

30
解释:
return相当于建立一个返回路径 相当于有一个箱子 箱子里保存的是
要返回的值 不会马上return返回 会看一下有没有finally 但是不会因为后面的finall而更改已经在返回路径中的值 
等finally执行完了 再完成return

运行异常与变异异常

运行时异常 -- 程序员犯的错
编译时异常 -- 为了错误做的提前准备
public class Demo05{
    public static void main(String[] args){
        try{
            FileInputStream inputStream = new FileInputStream("as.txt");
        }catch(FileNotFoundException e){
            System.out.println("兄弟 你没有这个文件");
        }

    }
}

理解

读取该路径下的文件
系统不知道你这个路径有没有问题
需要提前询问你这个路径有没有问题
需要提前询问一下 如果没有这个路径下的文件
编译时异常 是系统强制你要处理
处理方式1:添加try...catch(自己来处理)
处理方式2:可以把异常抛给上级去处理(这时和自己就没有关系了)
可以把问题抛给main函数 在main函数的函数声明上添加
throws 要抛出异常类型名

自定义异常

 * 需求:
 * 创建一个人类 有name 和 age
 * 要求 人类的年龄赋值时 要在 0120岁之前
 * 不用异常
package com.lanou3g;

public class Demo06 {
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("dp");
        try {
            person.setAge(150);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("赋值年龄超出范围");
        }
        System.out.println(person);
    }
}
class Person{
    private String name;
    private int age;
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    // throws 关键词在方法的声明上 标示这个方法可能会出现异常
    // 谁调用这个方法 这个异常就抛给了
    public void setAge(int age) throws Exception{
        // 需要在这个范围内 给名字赋值
        if(age <= 120 && age >= 0) {
            this.age = age;         
        }else {
            // 抛出一个异常
            // throw 后面跟的是 抛出的异常对象
            //Exception e = new Exception("兄弟 你是龟仙人吗");
            //throw  new Exception("兄弟 你是龟仙人吗");

            // 抛出自定义异常
            throw new AgeOutOfBoundsException("兄弟 你是龟仙人吗");
        }
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }

}

// 自定义异常
// 重点 要见名知意 并且跟系统学习
class AgeOutOfBoundsException extends Exception{

    /*
     * 序列化时 使用的ID
     */
    private static final long serialVersionUID = 1L;

    public AgeOutOfBoundsException() {
        super();
        // TODO Auto-generated constructor stub
    }

    public AgeOutOfBoundsException(String message) {
        super(message);
        // TODO Auto-generated constructor stub
    }
    // 写有参和无参的构造方法

}

Throwable中的方法

public class Demo07{
    public static void main(String[] args){
        Exception e = new Exception("这里可以输出错误信息");
        // 获取错误信息
        String message = e.getMessage();
        System.out.println(message); //输出:这里可以输出错误信息
        System.out.println(e); //输出:java.lang.Exception: 这里可以写错误信息
        // 打印错误信息 错误位置 异常类的类名
        e.printStackTrace(); //输出:java.lang.Exception: 这里可以写错误信息
    at com.lanou3g.Demo07.main(Demo07.java:7)

    }
}

示例:

需求:
// 无限输入整数 存放到集合中 打印 输入quit停止
// 希望在输入字符串的时候 让程序也能继续运行
package com.lanou3g;

import java.util.ArrayList;
import java.util.Scanner;

public class Demo08 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        ArrayList  list = new ArrayList<>();
        while(true) {
            System.out.println("请输入整数,输入quit 退出");
            String string = scanner.nextLine();
            if(string.equals("quit")) {
                break;
            }       
            try {           
                int parseInt = Integer.parseInt(string);
                list.add(parseInt);
            } catch (Exception e) {
                System.out.println("你输入错误 重新来吧");
            }

        }
        System.out.println(list);
    }
}

你可能感兴趣的:(JAVA高级应用之异常类处理)