Java异常处理

异常处理

1 异常概述

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

1.1堆内存OOM

  • xms10m:初始堆内存10m
  • xmx20m:最大堆内存20m

测试代码

public class Test1 {

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

    /**
     * xms:初始化堆内存
     * xmx:最大堆内存
     * @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();
        }
    }

}

设置jvm参数

  • xmx40m:最大堆内存大小40m
  • xms10m:初始堆内存大小10m
    点击Edit Configurations
    在这里插入图片描述
    点击Modify options
    在这里插入图片描述
    点击Add VM options
    在这里插入图片描述
    当然也可以点Alt+V
    在这里插入图片描述
    然后就可以出来VM options

在这里插入图片描述

1.2方法区(元空间)OOM

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();
        }
    }

}

设置最大方法区(元空间大小)(设置VM options)

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

1.3 StackOverflowError栈深度溢出异常

StackOverflowError:栈深度⼤于虚拟机所允许的深度

这里我们写一个递归

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

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

结果

前面代码

java.lang.StackOverflowError
	at a_basic.Test1.f1(Test1.java:38)
	at a_basic.Test1.f1(Test1.java:38)

1.3 其他异常

一. 不是maven项目拷贝junit的jar包到项目,是maven的话就在pom里添加依赖.

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>compile</scope>
        </dependency>

这里说一下拷贝

#创建lib目录
#拷贝junit的jar文件到目录

在这里插入图片描述
就可以写个test测试一下了
在这里插入图片描述

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 异常处理

2.1 try catch finally

    /**
     * ClassCastException
     * 类型转换异常
     */
    static void fn1() {
        Object o = "abc";
        Integer i = (Integer) o;

        int a = 1/0;

        String s = null;
        s.trim();


    }

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

        try {
            fn1(); 
        } catch (ClassCastException e) {
            System.out.println("ClassCastException");
            e.printStackTrace(); 
        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) { 
            e.printStackTrace();
        } finally {
            System.out.println("finally"); 
        
        System.out.println("步骤3");
    
    }

案例2:

public class Test2 {

    public static void fn1() {
        DataOutputStream out = null;
        try {
            out = new DataOutputStream(new FileOutputStream("d:\\a.txt"));
            out.writeChar(97);
            out.writeInt(1);
            out.writeChar(98);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static void main(String[] args) {
        fn1();
    }


}

2.2 throws

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

注意RuntimeException不需要catch异常

案例3:

    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) {
        //alt+enter:解决一切问题
        try {
            fn1();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } 

2.3 throw和自定义异常

throw:抛出一个异常,可以是一个自定义异常,语法

throw new MyException(); //抛出自定义异常
throw new RuntimeException(e);//抛出运行期异常
  1. 自定义异常
public class MyException extends Exception {

    public MyException() {
    }

    public MyException(String message) {
        super(message);
    }
}
  1. 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("学员编号不能为负数"); //抛出运行期异常
            //抛出自定义异常
            throw new RuntimeException(new MyException("学员编号不能为负数")) ;
        }
    }
}
  1. 测试类
public class Test1 {
    public static void main(String[] args) {
        Student s = new Student();
        s.setId(-1001);
        System.out.println(s.getId());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值