Java异常处理

1 异常概述

异常:程序执行过程中,产出的问题,因为异常的问题程序的正常的逻辑中断。
Java程序在执行过程中所发生的异常事件可分为两类:

  • Error: Java虚拟机无法解决的严重问题。 如: JVM系统内部错误、 资源耗尽等严重情况。
    StackOverflowError:栈深度溢出异常,比如递归方法,没有退出条件
    java.lang.OutOfMemoryError:OOM内存溢出异常,栈,堆,方法区,程序计数器不会发生
  • Exception: 其它因编程错误或偶然的外在因素导致的一般性问题, 可以使用针对性的代码进行处理。
    RuntimeException:运行期异常,编译是不需要处理
    ClassCastException
    ArrayIndexOutOfBoundsException
    ArithmeticException
    NullPointerException
    非RuntimeException:编译期需要处理(try catch 或者throws)
    FileNotFoundException
    IOException
    SQLException

异常层次结构图:

在这里插入图片描述

2 堆内存OOM

1.测试代码

public class Test1 {

    static class OOM{
        // int i = 0;
    }

    /**
     * xms:初始化堆内存
     * xmx:最大堆内存
     * 360146 10m
     * 810326 20m
     * 1215488 40m
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("前面代码");
        List<OOM> list = new ArrayList<>();
        int i=0;
        try {
            while (true) {
                i++;
                list.add(new OOM());
            }
        } catch (Throwable e) {
            System.out.println("=================多少次后发生异常:"+i);
            e.printStackTrace();
        }
    }
}

2.设置jvm参数

  • xmx20m:最大堆内存大小20m
  • xms10m:初始堆内存大小10m
    在这里插入图片描述
    3.运行结果
    在这里插入图片描述

3 方法区(元空间)OOM

1.测试代码:

public class MetaspaceDemo {

    static class OOM{}

    public static void main(String[] args) {
        int i = 0;//模拟计数多少次以后发生异常
        try {
            while (true){
                i++;
                Enhancer enhancer = new Enhancer();
                enhancer.setSuperclass(OOM.class);
                enhancer.setUseCache(false);
                enhancer.setCallback(new MethodInterceptor() {
                    @Override
                    public Object intercept(Object o, Method method, Object[] objects,
                                            MethodProxy methodProxy) throws Throwable {
                        return methodProxy.invokeSuper(o,args);
                    }
                });
                enhancer.create();
            }
        } catch (Throwable e) {
            System.out.println("=================多少次后发生异常:"+i);
            e.printStackTrace();
        }
    }
}

2.设置jvm参数

-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m

在这里插入图片描述
3.运行结果
在这里插入图片描述

4 StackOverflowError栈深度溢出异常

1.测试代码

static void f1(){
        int i=1;
        f1();
    }

    /**
     * StackOverflowError:栈寻址深度溢出异常,递归没有退出条件
     */
    @Test
    public void f2() {
        System.out.println("前面代码");
        f1();
        System.out.println("后续代码");
    }

2.运行结果
在这里插入图片描述

5 其他异常

1.测试代码

public class Test1 {

    /**
     * 空指针异常
     */
    @Test
    public void f3() {
        System.out.println("前面代码");

        String s = null;
        s.trim();

        System.out.println("后续代码");
    }

    /**
     * java.lang.ArithmeticException: / by zero:0作为除数异常
     */
    @Test
    public void f4() {
        System.out.println("前面代码");

        int i = 1/0;

        System.out.println("后续代码");
    }
}

2.运行结果

  • f3( )测试结果:
    在这里插入图片描述
  • f4( )测试结果:
    在这里插入图片描述

6 异常处理

在Java中,异常是指在程序执行过程中可能发生的错误或异常情况,这些情况可能导致程序中断或出现未预期的行为。常见的异常包括空指针异常、数组越界异常、算术异常等。

Java提供了异常处理机制来处理这些异常情况,异常处理主要包括以下几个关键字和语句:

try:用于包裹可能抛出异常的代码块,表示尝试执行其中的代码。
catch:用于捕获并处理异常,在try块中发生异常时,程序会跳转到对应的catch块进行处理。
finally:可选的代码块,在try块中的代码执行完毕后,无论是否发生异常,都会执行finally块中的代码。
throw:用于抛出异常,可以在程序中手动抛出异常。
throws:用于声明方法可能抛出的异常,在方法签名中声明。

1.try、catch、finally
异常处理的基本流程是:程序首先尝试执行try块中的代码,如果出现异常,则根据异常类型跳转到对应的catch块进行处理。如果try块中的代码没有发生异常,则跳过catch块,执行finally块中的代码(如果有的话)。无论是否发生异常,finally块中的代码都会被执行。
异常处理的基本语法结构如下:

try {
    // 可能抛出异常的代码块
} catch (异常类型1 变量名1) {
    // 处理异常1的代码
} catch (异常类型2 变量名2) {
    // 处理异常2的代码
} finally {
    // 可选的finally代码块
}

示例:

	@Test
    public void f5(){
    	//类型转换异常ClassCastException
        Object o = "abc";
        Integer i = (Integer) o; 
		//算术运算异常ArithmeticException
        int a = 1/0;             
		//空指针异常NullPointerException
        String s = null;
        s.trim();                
    }

    @Test
    public void f6() {
        System.out.println("步骤1");

        try {
            f5(); //共享单车车胎坏了
        } catch (ClassCastException e) {
            System.out.println("ClassCastException");
            //换了一个车
            e.printStackTrace(); //f6在调用f5的时候123行异常
        } catch (NullPointerException e) {
            //轱辘没了...
            System.out.println("NullPointerException");
            e.printStackTrace();
        } catch (Exception e) { //兜底,捕获除了上面2个异常的所有异常
            System.out.println("OthersException");
            e.printStackTrace();
        } finally {
            System.out.println("还共享单车"); //释放资源,必须执行的代码
        }

        System.out.println("步骤3");
        //运行期异常RuntimeException的子类,不需要处理,编译也不报错
    }

f6()方法中调用f5()方法时发生了ClassCastException异常,然后在f6()方法中捕获并处理了该异常。接着程序继续执行,输出 “还共享单车” 和 “步骤3”。其中,ClassCastException异常被catch块捕获,而后面的ArithmeticException异常和NullPointerException异常并没有被catch块捕获,所以它们没有被处理,直接抛出到上层调用栈,最后在控制台输出异常堆栈跟踪信息。

2.throws
throws:声明异常,当前方法不捕获(catch)异常,而是由调用这个方法的方法catch异常。
示例:

	public static void fn1() throws IOException {
        DataOutputStream out = new DataOutputStream(new FileOutputStream("d:\\c.txt"));
        out.writeChar(97); //若发生异常
        out.writeInt(1);
        out.writeChar(98);
        out.close(); //有可能执行不到
    }

    public static void main(String[] args) {
        try {
            fn1();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

3.throw与自定义异常
示例:
(1)自定义异常MyException

public class MyException extends Exception{
    public MyException() {
    }

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

(2)创建Student实体类

public class Student {
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        if(id > 0){
            this.id = id;
        }else {
            throw new RuntimeException(new MyException("id不能为负"));
        }
    }
}

(3)测试

public class Test {
    public static void main(String[] args) {
        Student s = new Student();
        s.setId(-1);
    }
}

结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值