Java-异常处理(编译时异常、运行时异常及处理机制,自定义异常)

个人简介

  • 大家好,我是翰慧腾。一名正在努力学JAVA的大一小白,本文章为初学的笔记,希望各位多多指教。
  • 欢迎点赞+收藏+留言
  • 你要批评指点四周风景,首先你要爬上屋顶

一、异常

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

常见的异常:数组索引越界、空指针异常、日期格式化异常等。

  • 异常一旦出现了,如果没有提前处理,程序就会退出JVM虚拟机而终止
  • 研究异常并且避免异常,然后提前处理异常,体现的是程序的安全、健壮性。

Java-异常处理(编译时异常、运行时异常及处理机制,自定义异常)_第1张图片

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

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

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

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

Java-异常处理(编译时异常、运行时异常及处理机制,自定义异常)_第2张图片

二、运行时异常

概述:直接继承自 RuntimeException或者其子类,编译阶段不会报错,运行时可能出现错误;通常是程序员业务没有考虑好或者是编程逻辑不严谨引起的程序错误。(说得直白点就是程序员技术不行导致的~~)

常见的运行时异常:

Java-异常处理(编译时异常、运行时异常及处理机制,自定义异常)_第3张图片

 

/**
 * @author hanhan
 * date 2022/4/24 8:48
 * 努力已经来不及了,你得拼命
 */
public class ExceptionDemo {
    public static void main(String[] args) {
        //数组索引越界异常ArrayIndexOutOfBoundsException
        int[] arr={1,2,3,4};
        System.out.println(arr[4]);//下标越界
        //空指针异常NullPointerException 直接输出没有问题,但是调用空指针的变量的功能就会报错
        String s=null;
        System.out.println(s);//不会出现异常,可以直接输出
        System.out.println(s.length());//字符串s本身都不知道自己指向哪,所以求长度更是不可能的
        //类型转换异常 ClassCastException
        Object o=123;
        String s1=(String) o;//运行错误,程序终止
        System.out.println(s1);
        //数学操作异常 ArithmeticException
        int i=10/0;
        System.out.println(i);
        //数字转换异常 NumberFormatException
        String s2="123aa";
        Integer ii=Integer.valueOf(s2);
        System.out.println(ii);

    }
}

三、编译时异常

概述:不是RuntimeException或者其子类的异常,编译阶段就会报错,必须处理,否则代码不通过,不能运行。

编译时异常作用:是担心程序员的技术不行,在编译阶段就爆出一个错误,目的在于提醒不要出错。(感谢编译时异常)

                                   Java-异常处理(编译时异常、运行时异常及处理机制,自定义异常)_第4张图片

四、异常的默认处理流程

Java-异常处理(编译时异常、运行时异常及处理机制,自定义异常)_第5张图片 

默认的异常处理机制并不友好,一旦真正出现异常,程序立即死亡。 

五 、编译时异常的处理机制

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

Java-异常处理(编译时异常、运行时异常及处理机制,自定义异常)_第6张图片 

异常处理方式1——throws

  • 用在方法上,可以将方法内部出现的异常抛出去给本方法的调用者处理。
  • 该方式并不友好,发现异常的方法自己不处理异常,如果异常最终抛出去给虚拟机将引起程序死亡 
  • 该方法可能显示抛出多个异常,但实际上只会抛出第一个异常,因为当第一个异常抛出去后,最终抛到虚拟机就会使程序死亡
  • 建议直接抛出exception

Java-异常处理(编译时异常、运行时异常及处理机制,自定义异常)_第7张图片 

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

/**
 * @author hanhan
 * date 2022/4/24 9:18
 * 努力已经来不及了,你得拼命
 */
public class ExceptionDemo_01 {
    public static void main(String[] args) throws ParseException {
        System.out.println("~~~~~start");
        parseTime("2022-02-22 12:12:12");
        System.out.println("~~~~~~end");
    }
    public static void parseTime(String data) throws ParseException {
        SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d=s.parse(data);
        System.out.println(d);
    }
}

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

  • 监视捕获异常,用在方法内部,可以将方法内部出现的异常直接捕获处理
  • 基于方式一,该方法出现异常后并不会导致程序死亡(还是挺友好的),发现异常的方法自己独立完成异常的处理,程序可以继续往下执行
  • 建议catch(Exception e),直接抛出exception

Java-异常处理(编译时异常、运行时异常及处理机制,自定义异常)_第8张图片

 

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

/**
 * @author hanhan
 * date 2022/4/24 9:18
 * 努力已经来不及了,你得拼命
 */
public class ExceptionDemo_01 {
    public static void main(String[] args) {
        System.out.println("~~~~~start");
        parseTime("2022-02-22 12:12:12");
        System.out.println("~~~~~~end");
    }
    public static void parseTime(String data) {
        try {
            SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date d=s.parse(data);
            System.out.println(d);
        } catch (ParseException e) {
            System.out.println("出现了异常哦~~");
        }
    }
}

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

  • 在开发中按照规范来说第三种方式是最好的:底层的异常抛出去给最外层,最外层集中捕获处理。
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author hanhan
 * date 2022/4/24 9:18
 * 努力已经来不及了,你得拼命
 */
public class ExceptionDemo_01 {
    public static void main(String[] args) {
        System.out.println("~~~~~start");
        try {
            parseTime("2022-02-22 12:12:12");
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("~~~~~~end");
    }
    public static void parseTime(String data) throws Exception {
            SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date d=s.parse(data);
            System.out.println(d);
        }
    }

六、运行时异常处理机制

  • 运行时异常编译阶段不会出现错误,是运行时候才可能出错的,所以编译阶段不处理也可以。
  • 按照规范建议还是处理:建议在最外层调用处集中捕获处理即可
/**
 * @author hanhan
 * date 2022/4/24 11:02
 * 努力已经来不及了,你得拼命
 * 运行时异常处理机制
 */
public class Exception_02 {
    public static void main(String[] args) {
        //建议在最外层try catch一下,就算出现异常程序也不会死亡
        System.out.println("~~~start");
        try {
            chu(10,0);
        } catch (Exception e) {
            e.printStackTrace();//打印异常信息
        }
        System.out.println("~~~~end");
    }
    public static void chu(int a,int b){
        System.out.println(a);
        System.out.println(b);
        int c=a/b;
        System.out.println(c);
    }
}

七、案例

Java-异常处理(编译时异常、运行时异常及处理机制,自定义异常)_第9张图片

import java.util.Scanner;

/**
 * @author hanhan
 * date 2022/4/24 11:22
 * 努力已经来不及了,你得拼命
 * 感受异常功能的强大
 */
public class Exception_Case {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        while(true){
            try {
                System.out.println("请输入价格:");
                String s=sc.nextLine();
                double d=Double.valueOf(s);
                if(d>0){
                    System.out.println("价格为"+d);
                    break;
                }else {
                    System.out.println("您输入价格不合理。请重新输入");
                }
            } catch (NumberFormatException e) {
                System.out.println("您输入信息有误,请重新输入");
            }
        }
    }
}

 八、自定义异常

自定义异常好处:

  • 可以使用异常的机制管理业务问题,如提醒程序员注意。
  • 同时一旦出现bug,可以用异常的形式清晰的指出出现错误的地方

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

  • 定义一个类继承Exception
  • 重写构造器
  • 在出现异常的地方用throw new 自定义抛出

throw和throws:

throws:用在方法声明上的,抛出方法内部的异常

throw:在方法内部直接创建一个异常对象,并抛出

​
​
/**
 * @author hanhan
 * date 2022/4/24 11:35
 * 努力已经来不及了,你得拼命
 * 自定义编译时异常
 */
public class ExceptionDemo_03 {
    public static void main(String[] args) {
        try {
            checkAge(12);
        } catch (AgeException e) {
            e.printStackTrace();
        }

    }
    public static void checkAge(int age) throws AgeException {
        if(age<=0||age>100){
            //抛出异常对象给调用者
            throw new AgeException(age+"是不正确的");
        }else{
            System.out.println("年龄正确");
        }
    }
}
class AgeException extends Exception{
    public AgeException() {
    }

    public AgeException(String message) {
        super(message);
    }
}

​

​

自定义运行时异常:提醒不强烈,编译阶段不报错,运行时才可能出现

  • 定义一个异常类继承RuntimeException类
  • 重写构造器
  • 在出现异常的地方用throw new自定义对象抛出
/**
 * @author hanhan
 * date 2022/4/24 15:24
 * 努力已经来不及了,你得拼命
 * 自定义运行时异常
 */
public class ExceptionDemo_04 {
    public static void main(String[] args) {
        try {
            checkAge(-12);
        } catch (Exception e) {
            System.out.println("您输入年龄有误");
        }
    }
    public static void checkAge(int age) {
        if(age<=0||age>100){
            //抛出异常对象给调用者
            throw new AgeException_(age+"是不正确的");
        }else{
            System.out.println("年龄正确");
        }
    }
}
class AgeException_ extends RuntimeException{
    public AgeException_() {
    }

    public AgeException_(String message) {
        super(message);
    }
}

你可能感兴趣的:(JAVA基础学习,java)