JAVA异常

2023-11-14

异常

1. 异常概述

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

1.1 堆内存OOM

堆溢出异常:

public class Test1 {

    static class OOM{}

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

设置jvm参数:

  • -Xmx40m:最大堆内存大小40m
  • -Xms10m:初始堆内存大小10m

执行结果:

1.2 StackOverflowError栈深度溢出异常

    // 栈寻址深度溢出异常 java.lang.StackOverflowError 一直将f2()方法压入栈中
    @Test
    public  void  f2()
    {
        new ExceptionTest().f2();
    }

1.5 方法区(元空间)OOM

利用了springboot框架自带的CGLIB的Enhancer类(通过不断循环创建这个新类的实例,模拟不断生成类的过程。)来不断的创建新的静态类来模拟元空间移除的实验。(注:一般静态类只会创建一次)

实验代码:

public class MetaspaceDemo {
//    static int  i =0;
//
//    public static void a() {
//        i++;
//        System.out.println(i);
//        a();
//    }
//
//
    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();
        }
    }


}

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

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

实验结果:

1.4 其他异常

使用测试类来进行实验:

1.导入junitjar包

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

2.进行实验

/**
     * 空指针异常
     */
    @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

try catch:

  • try:在try块中,我们编写可能会引发异常的代码。这些代码段被称为"受监控代码",因为程序会监视这些代码是否会抛出异常。
  • catch:如果在try块中的代码执行时抛出异常,catch块会捕获并处理该异常。在catch块中,我们可以编写处理异常的代码逻辑,以便程序在异常发生时不会崩溃,而是继续执行其他操作。catch块根据捕获到的异常类型来选择执行哪个代码块。

finally:

  • finally块是可选的,它跟在try-catch块之后。不论是否发生异常,finally块中的代码都会执行。通常在finally块中放置一些清理代码,比如释放资源(文件句柄、网络连接等)或确保某些操作总是会被执行。
  • 不管try块中的代码是否抛出异常,finally块中的代码都会被执行,除非在try块中执行了System.exit()或关闭了JVM等导致程序终止的情况。
package com.example.java.day7;/**
 * @User HASEE
 * @Author WeiXu
 * @Createtime 2023/7/26-26-10:09
 * @PACKAGE_NAME com.example.java.day7
 */

import org.junit.Test;

/**
 *@ClassName:ExceptionTest2
 *@author weixu
 *@date 2023/7/26 10:09
 */
public class ExceptionTest2 {
    static void f1()
    {
        //除数为0异常
        int i = 10 /0;
        //数组下标异常
        int[] i2 =new  int[4];
        i2[4] = 10;
        //空指针异常
        String string = null;


    }

    @Test //测试类必须是公开的  以下异常都为运行时异常的子类 运行期异常RuntimeException的子类,不需要处理,编译也不报错
    public void f2()
{

        try {
            f1();

            System.out.println("try内异常后的代码");
        }
        catch (ArithmeticException e)
        {
            e.printStackTrace();//打印异常信息
        }
        catch (NullPointerException e)//捕获空指针异常
        {
            e.printStackTrace();
        }
        catch (ArrayIndexOutOfBoundsException e)//捕获数组下标越界异常
        {
            e.printStackTrace();
        }
        catch (Exception e)//用来兜底的 捕获除erro以外的所有的异常
        {
            //输出异常信息
            e.printStackTrace();
        }
        finally {
            System.out.println("这条是必定执行的");//释放资源,必须执行的代码 如out.close(); 释放资源
        }

    System.out.println("异常后的代码");
    }
}

e.printStackTrace()

打印异常信息

案例2

package com.example.java.day7;/**
 * @User HASEE
 * @Author WeiXu
 * @Createtime 2023/7/26-26-11:04
 * @PACKAGE_NAME com.example.java.day7
 */

import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 *@ClassName:ExceptionTest3
 *@author weixu
 *@date 2023/7/26 11:04
 */

public class ExceptionTest3 {
    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)//捕获io异常
        {
            e.printStackTrace();
        } catch (Exception e) //捕获除erro以外的所有的异常
        {
            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异常

案例:

public class ExceptionTest3 {
    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)//捕获io异常
        {
            e.printStackTrace();
        } catch (Exception e) //捕获除erro以外的所有的异常
        {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                throw new RuntimeException(e);//抛出运行时异常
            }
        }
    }

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

2.3 throw和自定义异常

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

throw new MyException(); //抛出自定义异常
throw new RuntimeException(e);//抛出运行期异常

1.自定义异常

自定义异常的主要用途是提供更清晰的错误信息和更精细的错误处理,帮助代码更易读懂和维护。它们让程序员可以定义特定类型的异常,以便更好地描述和处理特定的错误情况。

案例:自定义一个当赋值的学生编号id小于等于0时的异常

MyException:

//自定义异常
    //public class MyException extends Exception{
    public class MyException extends RuntimeException{
    public MyException() {
    }
    public MyException(String message) {
        super(message);
    }
}

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("学生编号不能小于等于0"));
            throw new MyException("学生编号不能小于等于0"); //这样需要在本方法声明抛出异常
        }
    }
}

Test1类:

public class Test1 {

    @Test
    public void f1() {
        Student stu = new Student();
        stu.setId(-10);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA异常 的相关文章

随机推荐

  • 全球及中国家政服务产业前景建议与运营盈利分析报告2022版

    全球及中国家政服务产业前景建议与运营盈利分析报告2022版 修订日期 2022年2月 出版单位 鸿晟信合研究院 对接人员 周文文 内容分析有删减 了解详情可查看咨询鸿晟信合研究院专员 目录 第一章 家政服务行业基本概述 第二章 国际家政服务
  • java基础--向上转型

    为什么要用向上转型 因为为了让方法复用 只写一个以父类为形参的方法即可 不然形参为子类的话 每个子类都要单独写一个方法 那该多麻烦啊 只不过向上转型会丢失子类的特有方法 向下转型是强转 可使用instance判断 用来调用子类的特有方法 c
  • 【算法】二叉树广度优先(BFS)

    二叉树广度优先遍历 Depth First Search 这个算法是逐层遍历的 是从上到下 从左到右依次遍历 知道全部节点都被遍历完为止 由于需要记录每一层的节点 所以需要记录其对应的父节点的子节点 同时具有顺序性 为此需要使用队列来装遍历
  • 【记录】Django重复三步

    Step1 修改models py Step2 执行命令python manage py makemigrations app name Step3 再执行命令python manage py migrate 1 激活虚拟环境 启动服务器
  • Nginx 安装成功后,无法访问到默认页面

    安装 Nginx 后 无法访问到 Nginx 页面 1 查看 Nginx 是否启动成功 ps ef grep nginx 2 查看默认80端口是否分配给 Nginx netstat ntlp 如果前面几步都是正常的 则可以判断出是防火墙将8
  • 【SpringCloud-学习笔记】Docker基本操作

    1 镜像相关命令 镜像名称一般分两部分组成 repository tag 在没有指定tag时 默认是latest 代表最新版本的镜像 2 镜像操作命令 3 案例 从DockerHub中拉取一个nginx镜像并查看 首先去镜像仓库搜索ngin
  • 关于rfind

    rfind全名reversefind 与find相反 size type rfind const basic string str size type index size type rfind const char str size ty
  • Java面向对象编程

    下列关于线性链表的叙述中 正确的是 A 各数据结点的存储空间可以不连续 但它们的存储顺序与逻辑顺序必须一致 B 各数据结点的存储顺序与逻辑顺序可以不一致 但它们的存储空间必须连续 C 进行插入与删除时 不需要移动表中的元素 D 以上说法均不
  • IDEA 回退GIT代码

    IDEA 回退GIT代码 我们代码平时在IDEA开发完成后 提交代码到远程仓库的流程为 我们在提交代码到远程仓库的时候难免会发生提交了错误代码 要回滚到上个版本的情景 根据上面的流程我整理了一下三个场景的解决方案 1 idea中git回退已
  • 个人隐私问题

    近日 某高校毕业生在校期间窃取学校内网数据 收集全校学生个人隐私信息的新闻引发了人们对互联网生活中个人信息安全问题的再度关注 在大数据时代 算法分发带来了隐私侵犯 在享受消费生活等便捷权利的同时 似乎又有不少个人信息泄露的担忧 用隐私换便利
  • mybatisplus分页总是查到全部数据?

    这是因为版本的问题 在3 4 1及以上需要配置过滤器以实现分页 分页代码 gt Test void contextLoads6 Page
  • x86平台运行arm64平台docker 镜像

    本文介绍在x86服务器上安装qemu aarch64 statick仿真器 以实现x86服务器可以运行docker或docker compose镜像 报错信息 x86服务器默认不能运行ARM平台镜像 会提示如下错误 WARNING The
  • CMD命令读取某个目录下所有文件夹名或文件名

    CMD命令读取某个目录下所有文件夹名或文件名 CMD命令读取某个目录下所有文件夹名或文件名 要用到的dir命令 开始操作 CMD命令读取某个目录下所有文件夹名或文件名 目的是给自己留个笔记 要用到的dir命令 dir ad 只查看文件夹 d
  • sql:MySql create FUNCTION,VIEW,PROCEDURE

    use geovindu 函数 DELIMITER drop function if exists f GetDepartmentName CREATE function f GetDepartmentName did int return
  • TIOBE 发布 9 月编程语言排行榜:Python 登顶,Kotlin 重返前 20

    文章目录 前言 Kotlin 重新 杀回 Top 20 其他编程语言 Top 10 编程语言 TIOBE 指数走势 2002 2023 历史排名 1988 2023 编程语言 名人榜 2003 2022 说明 零基础Python学习资源介绍
  • ChatPPT 国内首个AI自动生成PPT效率工具

    场景 目前了解到ChatPPT使用首先需要下载安装MotionGo插件 安装完成之后在WPS或者office里面直接打开就可以了 方法 输入主题即可
  • 更改时间同步服务器bat文件,将windows server 2008设置成ntp时间同步服务器.bat

    echo off echo autor OAK echo off echo echo off REG ADD HKEY LOCAL MACHINE SYSTEM CurrentControlSet Services W32Time Para
  • matlab练习程序(Sepia Tone滤镜)

    我手机上有一个软件实现了很多图像滤镜 挺有意思 我打算都尝试一下 这个滤镜主要是实现老照片效果 代码很短 我就不详细介绍了 原图 处理后效果 matlab代码如下 clear all close all clc img imread len
  • xshell:全网最简单的将xshell连接图形界面linux虚拟机(ubantu,kali)

    问题提出 如何在windows连接图形界面linux虚拟机 我之前在网上找的教程都特别麻烦 要改这个改那个 相当复杂 机器配置 电脑windows10 虚拟机版本VMware 15 x xshell7 Linux kali linux最新版
  • JAVA异常

    异常 1 异常概述 异常 程序执行过程中 产出的问题 因为异常的问题程序的正常的逻辑中断 Java程序在执行过程中所发生的异常事件可分为两类 异常最顶层的类Throwable Error Java虚拟机无法解决的严重问题 如 JVM系统内部