java异常-Throwable-Error-Exception-异常处理-trycatch-throws-throw

异常

异常概述

  • 什么是异常?
    异常就是编译过程或运行过程中程序出现的不正常的情况;

  • java异常体系

异常体系

概述Throwable

Throwable类

  • 所有异常的祖宗类是java.lang.Throwable;
  • Throwable类是java语言中所有错误和异常的超类(父类)
  • Throwable类的两个子类:Error和Exception(异常)通常用于表示出现异常情况
  • Error:表示严重的问题,java程序是无法解决的,合理的应用程序不应该试图捕获。比如硬件存在问题、内存资源不足等问题()
  • Exception及其子类都是Throwable形式,表示合理应用程序可能想要捕获的条件
  • 除了RuntimeException及其子类、error及其子类,其余都是受检异常,受检异常就是编译期间必须处理的,否则不能通过编译,就更不能正常执行了。
  • RuntimeException是在java虚拟机的正常操作期间可以抛出的异常的超类;RuntimeException及其子类是未经检查的异常

ArrayIndexOutBoundsException类

  • 异常ArrayIndexOutBoundsException类继承于多个类,最开始继承于Object类、Throwable类
  • 异常ArrayIndexOutBoundsException类属于RuntimeException异常

Error和Exception

区别ErrorException
概念程序无法处理的,与代码编写者执行的操作无关,无法被捕获运行时错误,可以预料的异常,需要catch捕获然后进行处理
常见子类OutOfMemoryError 内存溢出(简称OOM)
StackOverflowError 栈溢出
RuntimeException 非受检异常(运行时异常)不强制使用catch捕获,根据实际场景判断
CheckedException 受检异常,必须通过Catch捕获
Error

有个OutOfMemoryError的错误,idea设置VM option还是不行,案例连接是:VM option

Exception

概述
java中的异常被分为两大类:编译时异常 和 运行时异常,也被称为 受检异常 和 非受检异常 英文名字是:CheckedException 和 RuntimeException 。
RuntimeException类及其子类被称为运行时异常;
其他的异常都是编译时异常;
受检异常 = 除了 RuntimeException及其子类 和 error及其子类

受检异常与非受检异常

区别受检异常
CheckedException
非受检异常(运行时异常)
RuntimeException
概念需要通过Catch捕获的异常不需要调用者显示捕获的异常
是否需要处理需要
必须显式处理,否则程序就会发生错误,无法通过编译
不需要
无需显式处理,但也可以和编译时异常一样处理
处理方法Add exception to method signature 表示把这个异常再往上抛
Surround with try/catch 表示使用try/catch捕获
常见异常NoSuchFieldException 表示该类没有指定名称抛出来的异常
IllegalAccessException 不允许访问某个类的异常
ClassNotFoundException 类没有找到抛出异常
IOException IO异常
NumberformatException 数值类型的格式错误
FileNotFountException 表示该类没有被找到跑出来的异常
ArrayIndexOutBoundsException 数组越界异常
NullPointerException 空指针异常
IllegalArgumentException 非法参数异常
NegativeArraySizeException 数组长度为负异常
IllegalStateException 非法状态异常
ClassCastException 类型转换异常
处理原因方便调用者接收到该异常清楚知道是什么异常从而方便修改
最大区别编译器强制执行,表示不受程序控制的异常运行时发生,指示编程错误

运行时异常:

// 25 -ThrowableDemo2
//运行时异常,编译阶段不报错,运行后会在控制台输出错误
public static void method(){
int[] arr = {1,2,3};
System.out.println(arr[3]);//java.lang.ArrayIndexOutOfBoundsException: 3
//解决:① 运行后返回程序进行修改;②在编译阶段处理,利用try..catch
}

编译时异常:

// 25-ThrowableDemo2
//编译时异常,案例采用Sting转 日期
public static void method2(){
    try {
        String s = "2022-2-7";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date d = sdf.parse(s);
        System.out.println(d);
        //输出结果是 : Mon Feb 07 00:00:00 CST 2022
        //也就是异常不一定会出现,只有当String和SimpleDateFormat对象的模式不匹配的时候才会出现异常
    }catch(ParseException e){
        e.printStackTrace();
    }
    //直接通过SimpleDateFormat对象.parse方法会报错;处理采用try..catch
    //编译时异常,不显示解决,程序无法通过编译,更不能执行。
    //编译时异常表示有可能会出现异常,比一定会出现异常。
}

JVM处理异常的默认方式

  • 把异常的名称、异常原因及异常出现的位置等信息输出在控制台
  • 程序停止执行

案例:

// 25
public class ExceptionDemo1 {
    public static void main(String[] args) {
        System.out.println("start");
        method();
        System.out.println("end");
    }
    public static void method(){
        int[] arr = {1,2,3};
        System.out.println(arr[3]);
    }
}

输出内容:

start
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
	at 
//运行时异常。
itheima25.ExceptionDemo1.method(ExceptionDemo1.java:11)
	at itheima25.ExceptionDemo1.main(ExceptionDemo1.java:6)
	
异常的名称 = java.lang.ArrayIndexOutOfBoundsException
异常的原因 = 3
异常出现的位置 = ExceptionDemo1.java:11

异常处理之try…catch

自己处理异常的原因:程序出现异常的时候,由于JVM(java虚拟机)默认处理方式会将程序在问题处停下,而在实际开发中程序的某一部分出现问题时,不应该影响后续的执行。
程序出现问题,有两种实现方案:try…catch 和 throws。
格式:

try{
	可能出现异常的代码;
}catch(异常类名 变量名){
	异常的处理代码;
}

执行流程:
①程序从try里面的代码开始执行
出现异常,会自动生成一个异常类对象 ‾ \underline{出现异常,会自动生成一个异常类对象} 出现异常,会自动生成一个异常类对象,该异常类对象将被提交给java运行时系统
③当java运行时系统接收到异常对象时,会到catch中去找匹配的异常类,找到后进行异常的处理
④执行完毕之后,程序还可以继续往下执行

案例:

// 25
// try..catch案例
public class ExceptionDemo2 {
    public static void main(String[] args) {
        System.out.println("start");
        method();
        System.out.println("end");
    }
    public static void method(){
        try {
            int[] arr = {1,2,3};
            System.out.println(arr[3]);
            //这里出现异常然后创建了对象 new ArrayIndexOutBoundsException();
            //将该对象提交给java运行时系统
        }catch(ArrayIndexOutOfBoundsException e){//异常类名  变量名(对象名)
            //这里的异常类名就是 数组越界后 JVM默认处理方式输出的类名
//            System.out.println("数组的索引溢出");
            //一般工程中不采用这种形式,都是会弹出一个页面,
            //或者使用对象.printStackTrace()
            e.printStackTrace();
            /*java.lang.ArrayIndexOutOfBoundsException: 3
	at itheima25.ExceptionDemo2.method(ExceptionDemo2.java:13)
	at itheima25.ExceptionDemo2.main(ExceptionDemo2.java:7)*/
            //输出结果是 上述内容,和 不加try..catch一样 
           // 但是不同的是 添加try.catch 后续的代码会继续执行,而采用JVM默认异常处理模式 输出上述内容,程序运行停止
        }
    }
}

Throwable的成员方法

Throwable是所有错误和异常的祖宗类,只要属于这个体系的,都可以使用它的成员方法。

案例采用:ArrayIndexOutBoundsException

方法名说明案例
public String getMessage()返回此throwable的详细消息字符串输出 3
异常的原因
public String toString()返回此throwable可抛出的简短描述
包括异常类名、异常原因
java.lang.ArrayIndexOutOfBoundsException: 3
异常类名、异常原因
public void printStackTrace()把异常的错误信息输出在控制台
输出包含异常类名、原因、位置信息
java.lang.ArrayIndexOutOfBoundsException: 3
at itheima25.ThrowableDemo.method(ThrowableDemo.java:14)
at itheima25.ThrowableDemo.main(ThrowableDemo.java:8)
输出异常类名、原因、位置

下述内容都在try…catch中的catch部分。
e.getMessage()

 System.out.println(e.getMessage());
// 输出结果是 3 
// 而不是视频中的 Index 3 out of bound for length 3
//输出异常的原因 
// 输出不同可能是jdk版本不一样的原因。

e.toString()

System.out.println(e.toString());
//输出内容 = java.lang.ArrayIndexOutOfBoundsException: 3
包括异常类名、异常原因

e.printStackTrace()

e.printStackTrace();
输出包含异常的类名、原因、位置信息
/*
java.lang.ArrayIndexOutOfBoundsException: 3
at itheima25.ThrowableDemo.method(ThrowableDemo.java:14)
at itheima25.ThrowableDemo.main(ThrowableDemo.java:8)
*/

案例:

// 25
// throwable 的三个常用方法
// getMessage、toString、printStackTrace;
public class ThrowableDemo {
    public static void main(String[] args) {
        System.out.println("start");
        method();
        System.out.println("end");
    }
    public static void method(){
        try {
            int[] arr = {1,2,3};
            System.out.println(arr[3]);
        }catch(ArrayIndexOutOfBoundsException e){
        //  getMessage()
            System.out.println(e.getMessage());
            //输出结果是 3 而不是视频中的 Index 3 out of bound for length 3
            //输出异常的原因
            System.out.println(e.toString());
            //输出内容 = java.lang.ArrayIndexOutOfBoundsException: 3
            // 包括异常类名、异常原因
            e.printStackTrace();
            //输出包含异常的类名、原因、位置信息
            /*
            java.lang.ArrayIndexOutOfBoundsException: 3
            at itheima25.ThrowableDemo.method(ThrowableDemo.java:14)
            at itheima25.ThrowableDemo.main(ThrowableDemo.java:8)
	*/
        }
    }
}

Throws异常处理

原因:
通过try…catch…可以对异常进行处理,但并不是所有的情况我们都有权限进行异常的处理,处理不了的时候,需要采用java提供的throws处理方案

格式:

throws 异常类名;
这个格式是跟在方法的括号后面的。
// 也就是:
public static void 方法名() throws 异常类名{}

异常处理:
①编译时异常必须要进行处理。两种方案:try…catch 或者 throws 如果采用throws这种方案,将来谁调用谁处理
②运行时异常可以不处理。出现问题后,需要我们回来修改代码

案例:

//28
public class ThrowsableDemo {
    public static void main(String[] args) {
        System.out.println("start");
//        method();
        try {
            method2();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println("end");
    }
    //编译时异常
    public static void method2() throws ParseException {
        String s = "2022-2-8";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date d = sdf.parse(s);
        //点击alt+enter 弹出窗口选择 Add exception to method signature
        //会在方法名的括号后面加上 throws ParseException
        //这种方式并没有真正的解决异常,要先解决还是得通过try..catch
        System.out.println(d);
        //输出 Tue Feb 08 00:00:00 CST 2022
    }
    //运行时异常
    public static void method() throws ArrayIndexOutOfBoundsException{
        int[] arr = {1,2,3};
        System.out.println(arr[3]);
        // 这里会报运行时异常,可以通过try..catch..解决
        // 并没有解决异常,只是将异常抛出
    }
}

自定义异常throw

概述

自定义异常类格式:

public class 异常类名 extends Exception{
	无参构造方法;
	有参构造方法;
}

自定义异常类

// 28-test2
public class ScoreException extends Exception {
    public ScoreException(){}
    public ScoreException(String message){
        super(message);
        //这样写的原因是:
        按下ctrl + b 跟进,(这些传递都是构造方法进行的)
        把ScoreException类中的message传到Exception类中
        ===》把Exception类中的message传到Throwable类中,
        message就传递给了detailmessage,
        detailmessage是Throwable的成员变量,可以通过getMessage方法得到、也可以通过printStackTrace方法得到。
    }
}
异常的使用

手动抛出异常 throw new 异常名();或者 throw new 异常名(参数);

案例:

// 28-test2
//异常的使用:手动抛出异常 throw new 异常名();或者 throw new 异常名(参数);
public class Teacher {
    public void checkScore(int score) throws ScoreException {
        if(score <0 || score >100){
			* throw  new ScoreException();
			// 抛出的异常 不显示异常的原因
            // 通过throw抛出异常对象,如果自定义异常继承的是RuntimeException,则异常的抛出可以用throw抛出,也可以不用throw抛出
            
            * throw new ScoreException("分数超过范围,应该在0-100之间");
            // 抛出的异常 会显示异常的原因,就是上述括号中的文字
        }else{
            System.out.println("分数正确");
        }
    }
}

测试代码:

// 28-test2
public class TeacherDemo {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入分数:");
        int score = sc.nextInt();

        Teacher t = new Teacher();
        try {
            t.checkScore(score);
        } catch (ScoreException e) {
            e.printStackTrace();
        }
        ** 抛出异常采用无参构造方法 throw  new ScoreException();
		当分数出现异常的时候,会在控制台输出异常类名、异常位置等信息。不会输出异常原因。
        /*itheima28.test2.ScoreException
	at itheima28.test2.Teacher.checkScore(Teacher.java:6)
	at itheima28.test2.TeacherDemo.main(TeacherDemo.java:13)
	*/
        ** 抛出异常采用有参构造方法 throw new ScoreException(参数);
        当分数出现异常的时候,会在控制台输出异常类名、异常位置等信息。会输出异常原因,也就是自定义异常ScoreException中的参数。
        /*
        itheima28.test2.ScoreException: 分数超过范围,应该在0-100之间
		at itheima28.test2.Teacher.checkScore(Teacher.java:8)
		at itheima28.test2.TeacherDemo.main(TeacherDemo.java:13)
	*/
    }
}

Throws 和 Throw 的区别

区别ThrowsThrow
位置用在方法声明后面,跟的是异常类名用在方法体内,跟的是异常对象名
异常的处理对象表示抛出异常,由该方法的调用者来处理表示抛出异常,由方法体内的语句处理
是否一定存在否,表示出现异常的一种可能性,并不一定会发生这些异常是,执行throw一定抛出了某种异常

理解xhj:

  • 位置:
public static void 方法名() throws 异常类名{}
位于方法声明之后

throw new 异常类名();
在方法体内,跟着异常类对象名 = new 异常类名()
  • 异常处理的对象:
throws : 调用此方法的时候处理
try{
	方法名();
}catch(异常类 e){
	e.printStackTrace();
}

throw:在方法内进行处理
if(score > 100 || score < 0){
	throw new 异常类名("字符串,表示异常产生的原因描述,方便编程人员看");
}
else{
	System.out.println("输入内容正确");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值