异常处理,断言

本文详细介绍了Java中的断言机制,包括断言的功能、assert关键字的使用以及如何在IntelliJ IDEA中启用断言。同时,文章还深入探讨了Java异常处理,包括运行时异常、非运行时异常(检测异常)及其处理方式,如try-catch-finally结构、自定义异常类的实现等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、断言

1、功能

2、assert关键字表示

3、idea开启断言

二、异常处理

1、异常Exception

2、错误Error

1、运行时异常 RuntimeException的子类都是运行时异常

空指针异常NullPointerException

数学异常ArithmeticException

索引越界异常IndexOutOfBoundsException

数字格式化异常 NumberFormatException

类型转换异常 ClassCastException

2、非运行时异常(检测异常)

  检测异常(checked Exception)

try-catch-finally

1、发生异常被捕获处理

 2、发生异常没有被捕获处理

3、没发生异常

try-catch【多个catch】

try-finally finally内的代码一定执行

throw

throw和throws的区别

自定义异常类的实现方法和一般规则


一、断言

1、功能

JDK1.4版本开始,增加了断言机制;

断言用来进行调试,不在生产环境中使用;

换言之,断言是为了帮助程序员在编程的过程中,尽快发现错误并进行修改,使得程序在生产环境中正常运行;

2、assert关键字表示

assert <布尔表达式> assert <布尔表达式> : <错误信息>

  • 当布尔表达式的值是true时,忽略assert;
  • 当布尔表达式的值是false时,发生AssertionError错误,程序中断;如果用第二种形式,同时显示错误信息;

3、idea开启断言

Edit Configurations

找到要执行的类,在VM options添加 -ea

public class Test1 {
    public static void main(String[] args) {
        int i=10;
        assert i!=10:"断言错误!";
        System.out.println("i = " + i);
    }
}
/*
Exception in thread "main" java.lang.AssertionError: 断言错误!
    at a07.Test1.main(Test1.java:6)
*/

二、异常处理

1、异常Exception

异常指的是程序运行时发生的不正常事件;异常能够被程序处理,保证程序继续运行下去;例如除数为0、文件没有找到、输入的数字格式不对……

System.out.println("程序出现异常:");
System.out.println(100/0);//出现异常没有被正确处理,不能往下运行
System.out.println("程序继续运行");
java.lang.ArithmeticException: / by zero

 

2、错误Error

错误程序没法处理,eg内存泄漏。发生错误后,一般虚拟机会选择终止程序运行,需要修改代码解决

int[] a=new int[1024*1024*1024];
//java.lang.OutOfMemoryError对空间超出JVM内存,内存溢出,只能把长度改小

Throwable类(顶级父类)

Throwable类有两个子类:Exception和Error

所有异常都是Exception类的直接或间接子类

所有错误都是Error的直接或间接子类

1、运行时异常 RuntimeException的子类都是运行时异常

非检测异常(unchecked Exception),这些异常在编译期不检测,程序中可以选择处理,也可以不处理,编译通过,如果不处理运行时会中断,但是编译没问题;

空指针异常NullPointerException

发生前提:当对一个空对象既没有初始化依然为null的对象调用属性或方法时

String str1 = "";//输出0,str1为空字符串,长度为0,存在
String str = null;//不存在
System.out.println(str.length());
//str为null,对象为null,调用length(),就会报NullPointerException异常

数学异常ArithmeticException

   整数除以0

System.out.println(10.0/0);//**浮点型不抛出异常**,输出Infinity
System.out.println(10/0);//**整数抛出异常**java.lang.ArithmeticException

索引越界异常IndexOutOfBoundsException

    数组索引:ArrayIndexOutOfBoundsException

    字符串索引:StringIndexOutOfBoundsException

    当访问字符串中的字符或数组中的元素超过了其长度时

//int[] a=new int[3];
//System.out.println(a[3]);//数组索引越界,出现异常java.lang.ArrayIndexOutOfBoundsException: 3(冒号左边异常类型,右边提示信息)
String str="hello";
//打印字符串索引5的字符,会出现异常StringIndexOutOfBoundsException: String index out of range: 5
System.out.println(str.charAt(5));//字符串长度为5,索引 最大值为4,访问第5个字符,将发生索引越界异常

数字格式化异常 NumberFormatException

    把字符串转成数字,字符串内容不是数字时发生

String str="abc";
System.out.println(Integer.valueOf(str));
//数字格式化出现异常NumberFormatException: For input string: "abc"

类型转换异常 ClassCastException

    把父类对象转换成不相关的子类类型时

Object o=new Object();
//编译没有问题,向下造型,能不能转成功就不一定了
String s=(String ) o;
System.out.println(s);
ClassCastException:java.lang.Object cannot be cast to java.lang.String

2、非运行时异常(检测异常)

  检测异常(checked Exception)

    编译期处理且必须处理,如果不处理将会发生编译期错误

//检测异常不处理,编译不能通过,强行要求处理  
FileReader fileReader=new FileReader("a.txt");
  • 标准异常处理流程

try-catch-finally

try{
  可能抛出异常的代码块;
}catch(异常类型  变量名){
    处理异常的代码;
}finally{
    不管什么情况,一定被执行的代码块; 
}

1、发生异常被捕获处理

如果catch住异常执行catch的代码,后面的代码不会正常执行 

public class CheckExceptionTest {
    public static void main(String[] args) {
        test1();
        System.out.println("main方法运行结束");//
    }
    private static void test1(){
        //try-catch处理异常
        //出现异常后不影响下面代码的执行
        try {
            int x = 100;
            int y = 0;
            //代码运行发生异常
            System.out.println("x/y" + (x / y));
           //下面的不会执行,如果catch住异常执行catch的代码,后面的代码不会正常执行
           //没有catch住,程序就会退出
            System.out.println("计算完成");
        }catch (ArithmeticException e){
            System.out.println("除法发生了异常,进行了处理");
        }
    }
}
/*
除法发生了异常,进行了处理
main方法运行结束
*/

 2、发生异常没有被捕获处理

异常类型匹配

catch (NullPointerException e) {
//异常处理机制将ArithmeticException与catch语句的异常类型匹配
    System.out.println("发生了异常");
    //匹配失败,不运行catch代码块,异常没有被处理;
}

3、没发生异常

所有代码正常运行,但catch的代码不运行 

public class CheckExceptionTest {
    public static void main(String[] args) {
        test1();
        System.out.println("main方法运行结束");
    }

    private static void test1() {
        //try-catch处理异常
        try {
            int x = 100;
            int y = 10;
            //代码运行没有发生异常,所有代码正常运行,但catch的代码不运行
            System.out.println("x/y=" + (x / y));
            //下面的不会执行,如果被catch住异常了,那么执行catch的代码,后面的代码不会正常执行,没有catch住,程序就会退出
            System.out.println("计算完成");
        } catch (NullPointerException e) {
            System.out.println("除法发生了异常,进行了处理");
        }
    }
}

try-catch【多个catch】

匹配顺序由上到下,Exception e放在最下面

catch语句的异常类型必须从子类到父类的顺序,否则编译错误;

try {
    数学计算
    int x=100;
    int y=0;
    System.out.println("x/y="+(x/y));
    空指针
    String s=null;
    System.out.println(s.length());
    其他
    int[] a=new int[3];
    System.out.println(a[3]);
    System.out.println("test2()运行完成");
  }catch (ArithmeticException e){                 
  //多个catch 有一个被捕获了就不再匹配其他的catch
    System.out.println("数学计算发生了异常");
  }catch (NullPointerException e){
    System.out.println("空指针异常");
  }catch (Exception e){            
  //**匹配顺序由上到下,Exception e放在最下面**,如果放到第一个后面的catch便没有意义永远不会被执行,所以编译报错
    //todo 写日志
    System.out.println("其他异常");
  }

try-finally finally内的代码一定执行

throw

new一个异常对象,throw关键字交给异常处理机制去处理;

throw关键字在方法体中使用

throw 异常对象;throw new Exception(); 或者catch(Exception e){ throw e;}

  • 运行时异常是JVM自动抛出

  • 非运行时异常需要程序员用throw抛出

    • throw

      由于抛出了Exception,是非运行时异常,所以编译器检测要处理:

      1、try-catch-finally //没意义

      2、不处理,用throws声明异常 //常用

    • throws

      用在方法声明处,声明该方法可能发生的异常类型

      可声明多种类型,用逗号隔开

      抽象方法也可以用throws声明该方法可能抛出的异常类型

    • 调用带有throws方法必须处理这些异常

      真正抛出和处理的异常是声明的子类或本身类,不能比他大

public class Calculator {
    /**
     * 除法计算
     *
     * @param x
     * @param y
     * @throws Exception 方法声明了  抛出Exception异常(表示这个方法运行过程中会有Exception发生的可能性)
     */
    public void div(int x, int y) throws Exception {
        //如果y==0,除法会抛异常
        if (y == 0) {
            throw new Exception("异常测试,主动抛出异常");//没人处理,编译报错
        }
        System.out.println(x / y);
    }

    public static void main(String[] args) throws Exception {
        Calculator calculator = new Calculator();
       try{
            calculator.div(10, 0);
//必须要处理异常,不处理不能通过编译try-catch或者throws Exception,二者选一就行
        }catch (Exception e){
            System.out.println("div方法发生了异常:"+e.getMessage());
        }
    }
}

先统一处理,再次抛出 

public class Calculator {
    public void div(int x, int y) throws Exception {
        try {
            if (y == 0) {
                throw new Exception("异常测试,主动抛出异常");
            }
        }catch (Exception e){
            System.out.println("处理数据");
            //再次抛出
            throw e;
        }
        System.out.println(x / y);
    }
    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        try{
            calculator.div(10, 0);
        }catch (Exception e){
            System.out.println("div方法发生了异常:"+e.getMessage());
        }
    }
}

不管有没有异常作统一处理,有异常声明抛出可以用try-finally 

public void div(int x, int y) throws Exception {
        //如果y==0,除法会抛异常
        try {
            if (y == 0) {
                throw new Exception("异常测试,主动抛出异常");
            }
            System.out.println(x / y);
        }finally {
            System.out.println("关闭文件句柄");
        }
    }

throw和throws的区别

throw就是自己处理一个异常,要么自己捕获异常try...catch,要么抛出一个异常(throws 异常)

throws在方法后边声明异常,自己不想对异常做出任何的处理,告诉别人自己可能出现的异常,交给别人处理

  1. throw:抛出一个具体的异常类型

    用在方法体内,后面是异常对象名,只能抛出一个异常对象名

    由方法体内的语句处理 ,throw是抛出了异常,执行throw则一定抛出了某种异常

  2. throws:用来声明一个方法可能产生的所有异常,不做任何处理而是将异常往上传,谁调用我我就抛给谁。

    用在方法声明后面,跟的是异常类名,可以跟多个异常类名,用逗号隔开

    由该方法的调用者来处理 ,throws表示出现异常的一种可能性,并不一定会发生这些异

自定义异常类的实现方法和一般规则

自定义异常类实现

public class DataValueException extends **Exception**{
    public DataValueException(){
    }
    public DataValueException(String message){
        super(message);
    }
    /**
     * 构造方法
     * @param e** 异常对象
**     */
    public DataValueException(Throwable e){
        super(e);
    }
    public DataValueException(String message,Throwable e){
        super(message,e);
    }
}

使用自定义异常与使用API标准异常一样 

public class Employee {
    private String name;
    private double salary;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getSalary() {
        return salary;
    }
    //工资小于等于2500抛出异常
    public void setSalary(double salary) throws DataValueException {
        if(salary<=2500){
            throw new DataValueException("工资小于2500太低了,涨工资");
        }else{
            this.salary = salary;
        }
    }
    public static void main(String[] args) {
        Employee e=new Employee("肖战王一博",2026);
        try {
            e.setSalary(2400);
        } catch (DataValueException ex) {
            //打印ex对象DataValueException的toString方法,DataValueException没有冲洗toString(),然后找父类Exception,也没有,再找Throwable,
            System.out.println(ex);
        }
    }
    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }
}
//com.bjyx.myException.DataValueException: 工资小于2500太低了,涨工资
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值