2022-07-29 第八小组 学习笔记

目录

异常

异常体系

Error:系统级别问题、JVM退出等,代码无法控制。

Exception: java.lang包下,称为异常类,它表示程序本身可以处理的问题

常见的运行时异常

​编辑编译时异常

异常的默认处理流程(不好)

异常的处理机制

编译时异常的处理形式有三种

异常处理方式1—— throws

异常处理方式2——try...catch...

异常处理方式3——前两者结合

运行时异常处理机制

异常处理代码更稳健的案例

自定义异常

自定义编译时异常

自定义运行时异常

Throw和throws的区别

finally关键字

总结

今日分享


异常

异常是程序在“编译”或者“执行”的过程中可能出现的问题,注意:语法错误不算在异常体系中。

比如:数组索引越界、空指针异常、数字转换异常、日期格式化异常、类型转换异常、算数异常(数学异常)


异常体系

Error:系统级别问题、JVM退出等,代码无法控制。

Exception: java.lang包下,称为异常类,它表示程序本身可以处理的问题

RuntimeException及其子类运行时异常(运行时出现的异常),编译阶段不会报错。(空指针异常,数组索引越界异常)

除RuntimeException之外所有的异常编译时异常(编译时出现的异常),编译期必须处理的,否则程序不能通过编译。(日期格式化异常)。

常见的运行时异常

运行时异常:直接继承自RuntimeException或者其子类,编译阶段不会报错,运行时可能出现的错误。

数组索引越界异常:ArraylndexoutOfBoundsException
空指针异常:NullPointerException,直接输出没有问题,但是调用空指针的变量的功能就会报错。
数学操作异常:ArithmeticException
类型转换异常:ClassCastException
数字转换异常:NumberFormatException

 数组索引越界异常ArraylndexoutOfBoundsException

  //数组索引越界异常:ArraylndexoutOfBoundsException
public static void main(String[] args) {
        int arr[] = {10, 20, 30};
        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);
        System.out.println(arr[3]);
      }
}

注意:把后报的错误放到上面,先进的在下面,后进的在上面,后进先出是栈。因此是异常栈信息。

空指针异常NullPointerException,直接输出没有问题,但是调用空指针的变量的功能就会报错。

//空指针异常:NullPointerException,直接输出没有问题,但是调用空指针的变量的功能就会报错。
 
public class Cjiande {
   public static void main(String[] args) {
        System.out.println("开始");
     //空指针异常:NullPointerException,直接输出没有问题,但是调用空指针的变量的功能就会报错。
        String name=null;
        System.out.println(name);//没问题
        System.out.println(name.length());
    }

}

数学操作异常:ArithmeticException

  //数学操作异常:ArithmeticException
int num1 = 10/0;

类型转换异常ClassCastException

       //类型转换异常
         Object O=23;
        String a= (String) O;

 数字转换异常:NumberFormatException

String s="122";
        Integer integer=Integer.valueOf(s);
        System.out.println(integer);//正常输出

  System.out.println("-----------------------");

//数字转换异常:NumberFormatException
String s="122ass";
        Integer integer=Integer.valueOf(s);//运行出错,程序终止
        System.out.println(integer);

编译时异常

不是RuntimeException或者其子类的异常,编译阶就报错,必须处理,否则代码不通过。


package com.jr.morning.test;

import java.text.SimpleDateFormat;
import java.util.Date;

public class ExceptionDemo {
    public static void main(String[] args) {
        String date="2022-07-29  11:18:25";
        //创建一个简单日期格式类,解析字符串时间成为日期对象
        SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");//格式一定要与上面的格式相同,否则解析失败
        Date d=sim.parse(date);//报错,(查看下图
        System.out.println(d);
    }

}

下图就是编译时异常 

 解决方法:alt+Enter,选择第一个第二个都行。

异常的默认处理流程(不好)

①默认会在出现异常的代码那里自动的创建一个异常对象:ArithmeticException。

②异常会从方法中出现的点这里抛出给调用者,调用者最终抛出给JVM虚拟机。

③虚拟机接收到异常对象后,先在控制台直接输出异常栈信息数据。
④直接从当前执行的异常点干掉当前程序。
⑤后续代码没有机会执行了,因为程序已经死亡。

异常的处理机制

编译时异常是编译阶段就出错的,所以必须处理,否则代码根本无法通过

编译时异常的处理形式有三种

1.出现异常直接抛出去给调用者,调用者也继续抛出去。(出现异常,不管,往上抛,都不管,层层往上抛<默认处理方式>)

2.自己捕获处理,不麻烦别人。

3.前两者结合,出现异常直接抛出去给调用者,调用者捕获处理。

异常处理方式1—— throws

throws:用在方法上,可以将方法内部出现的异常抛出去给本方法的调用者处理。

这种方式并不好,发生异常的方法自己不处理异常,如果异常最终抛出去给虚拟机将引起程序死亡。

抛出异常格式:

方法 throws 异常1,异常2,异常3..{

}

案例解析:

定义一个parseTime类,现在parse是报错的,要给它往外抛。

package com.jr.morning.test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExceptionDemo {
    public static void main(String[] args) throws ParseException {
        System.out.println("开始");
        parseTime("2022-07-28  11:52:20");
        System.out.println("结束");
        //        String date="2022-07-29  11:18:25";
//        //创建一个简单日期格式类,解析字符串时间成为日期对象
//        SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");//格式一定要与上面的格式相同,否则解析失败
//        Date d=sim.parse(date);
//        System.out.println(d);
    }
    public static void parseTime(String date){
        SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
        Date d=sim.parse(date);//报错!!
        System.out.println(d);
    }

}

 加throws ParseException

    public static void parseTime(String date) throws ParseException {
        SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
        Date d=sim.parse(date);
        System.out.println(d);
    }
}

规范做法:

方法 throws Exception{

}

异常处理方式2——try...catch...

格式:                                                                       建议格式:

 快速创建try...catch...的快捷键:全选上,CTRL+alt+T

package com.jr.morning.test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExceptionDemo {
    public static void main(String[] args)  {
        System.out.println("开始");
        parseTime("2022-07-28  11:52:20");
        System.out.println("结束");
        //        String date="2022-07-29  11:18:25";
//        //创建一个简单日期格式类,解析字符串时间成为日期对象
//        SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");//格式一定要与上面的格式相同,否则解析失败
//        Date d=sim.parse(date);
//        System.out.println(d);
    }
    public static void parseTime(String date) {
        try {
            SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
            Date d=sim.parse(date);
            System.out.println(d);
        } catch (ParseException e) {
            //解析出现问题
            System.out.println("出现了解析时间异常");
        }
    }

}

异常处理方式3——前两者结合

方法直接将异通过throws抛出去给调用者

调用者收到异常后直接捕获处理。

package com.jr.morning.test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExceptionDemo {
    public static void main(String[] args)  {
        System.out.println("开始");
        try {
            parseTime("2022-07-28  11:52:20");
            System.out.println("功能操作成功");
        } catch (ParseException e) {
            e.printStackTrace();
            System.out.println("失败");
        }
        System.out.println("结束");
        //        String date="2022-07-29  11:18:25";
//        //创建一个简单日期格式类,解析字符串时间成为日期对象
//        SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");//格式一定要与上面的格式相同,否则解析失败
//        Date d=sim.parse(date);
//        System.out.println(d);
    }
    public static void parseTime(String date) throws ParseException {

            SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
            Date d=sim.parse(date);
            System.out.println(d);

    }

}

运行时异常处理机制

运行时异常编译阶段不会出错,是运行时才可能出错的,所以编译阶段不处理也可以。

按照规范建议还是处理:建议在最外层调用处集中捕获处理即可。

package com.jr.morning.test;

/*运行处理机制*/
public class ExceptRunTime {
    public static void main(String[] args) {
        System.out.println("开始");
        try {
            chu(1, 0);//③
        } catch (Exception e) {
           e.printStackTrace();//④
        }
        System.out.println("结束");
    }

    public static void chu(int a, int b) {// ②

        int c = a / b;①
        System.out.println(c);
    }
}

 先从①抛到②,再从②抛到③,然后由④去打印出来的。

异常处理代码更稳健的案例

需求

键盘录入一个合理的分数为止(必须是数值,值必须大于0)。

分析

定义一个死循环,让管理员不断输入分数直到正确位置

package com.jr.morning.test;

import java.util.Scanner;

public class Test1 {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
    while(true){
        System.out.println("请输入合法分数:");
        String score=scanner.nextLine();
        //转换成double类型的分数
        double score1=Double.valueOf(score);
        //判断分数是否大于0
        if(score1>0){
            System.out.println("分数为:"+score1);
            break;
        }else {
            System.out.println("分数必须为正数");

        }
    }

    }
}

 我们发现可以运行,但是可能存在乱输入的情况,比如说输入一个"43.2.6.5aaa",转不了double

程序挂了...不稳健。因此,可以将判断的代码放到try..catch..里面。只要catch拦截到了异常,说明用户在乱输入,不然不能拦截到异常,一旦拦截到乱输入的数据后,程序就不会死亡 ,这样可以让用户循环再继续输入数据。

package com.jr.morning.test;

import java.util.Scanner;

public class Test1 {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
    while(true){
        try {
            System.out.println("请输入合法分数:");
            String score=scanner.nextLine();
            //转换成double类型的分数
            double score1=Double.valueOf(score);
            //判断分数是否大于0
            if(score1>0){
                System.out.println("分数为:"+score1);
                break;
            }else {
                System.out.println("分数必须为正数");

            }
        } catch (Exception e) {

            System.out.println("输入有误!请重新输入...");
        }
    }

    }
}

自定义异常

自定义编译时异常

定义一个异常类继承Exception

重写构造器。
在出现异常的地方用throw new自定义对象抛出

作用:编译时异常是编译阶段就报错,提醒更加强烈,一定需要处理!!

案例 需求:认为年龄小于18,大于60岁就是异常。

首先定义一个自定义异常

package com.jr.morning.test;
/*把年龄非法做成一个自定义编译时异常
* 1.继承Exception
* 2.重写构造器*/
public class AgeException extends Exception{
    public AgeException() {
    }

    public AgeException(String message) {//可以把原因写进去
        super(message);
    }
}
package com.jr.morning.test;

import com.jr.afternoon.AgeException;

/*需求:认为年龄小于18,大于60岁就是异常 */
public class ExceptDemo {
    public static void main(String[] args) {
        try {
            checkAge(34);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void checkAge(int age) throws AgeException {
        if (age<18||age>60){
            //抛出去一个异常给调用者
            //throw:在方法内部直接创建一个异常对象,并从此点抛出
            //throws:用在方法申明上面,抛出方法内部的异常
            throw new AgeException(age+"   是非法的");
        }else {
            System.out.println("年龄合法");
        }
    }
}

自定义运行时异常

定义一个异常类继承RuntimeException.重写构造器。

在出现异常的地方用throw new自定义对象抛出!
作用:提醒不强烈,编译阶段不报错!以运行时才可能出现!!

Throw和throws的区别

1.位置不同
throw:方法的内部
throws:方法的声明处

2.内容不同
throw new 异常();
throws+异常类型的对象(可以有多个类型 用,连接)

3.作用不同
throw:异常的源头,制造异常
throws:声明异常,告诉方法的调用者,这个方法可能会出现的异常,然后调用者对这些异常进行处理

finally关键字

1.finally是可选的

2.finally 中声明的是一定会被执行的代码,即使catch中又出现异常,try中有return语句,catch中可能也会有return语句。

3.一般finally中的代码都是用来释放资源

案例:

package com.jr.morning.test;

import static com.jr.morning.test.ExceptRunTime.chu;

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

            System.out.println("开始");
            try {
                chu(1, 1);
            } catch (Exception e) {
                //e.printStackTrace();
                int[]arr=new int[5];
                System.out.println(arr[5]);
            }finally {
                System.out.println("我是美女");
            }

        }
        public static void chu(int a, int b) {
            int c = a / b;
            System.out.println(c);
        }
}

总结

今天学习了异常,包括运行时异常、编译时异常。以及两种异常的处理方式、自定义异常、finally关键字。总体来说掌握得还不错,后续还要多练习项目加深巩固。

今日分享

竹深树密虫鸣处,时有微凉不是风。——杨万里《夏夜追凉》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值