Java自定义异常理解

article/2025/10/2 9:19:21

前言:看了许多博客和书,都对自定异常一笔带过,总让人感觉莫名奇妙,一直在问自己一个问题,我们能很好的解决异常就很不错了,为什么还要自己自定义异常,让自己去自找麻烦呢?后来我才理解自定义异常有自己的妙用。

Java错误与异常的基本概念:

1.java中异常均继承自Throwable,其有两个重要的直接子类error与exception.

2.java错误error,大部分是由虚拟机爆出来的错误,是程序无法处理的错误,如OutOfMemoryError,当JVM需要更多内存空间而得不到满足时,就会爆出OutOfMemoryError

3.Exception,异常,其下分类很多,如可查异常与不可查异常,运行时异常与非运行时异常,基本概念一样,只是说法不同罢了。其有个重要的子类即RuntimeException运行时异常,其它直接子类都归为非RuntimeException,如IOException,SQLException等。

       a.非RuntimeException是在代码书写时,编译器给你检查提示你要进行try catch或throws处理。

       b.RuntimeException,编译器不会帮你自动检查,当你运行程序时,虚拟机才会给你爆出错误让你去处理,这个往往是我们编码逻辑或不规范导致的

下面我们来看看java异常类结构层次图:


异常中的try,catch,throw,throws,finally,相信都能很好理解,下面我重点来说自定义异常了。


JAVA自定义异常:

自定义异常几步骤:

1.自定义一个类,集成自Exception

2.重写父类Exception所有的公共方法

3.重载构造函数


那为什么要自定义异常呢,这就涉及到项目结构中的分层思想了,根据MVC架构,一个项目可大体分为3个层次,

1.是模型层model,这个往往与数据库中的表结构相对应,今天内容不涉及该层可忽略。

2.是业务逻辑层Contorler,往往处理的是业务逻辑的,如对数据库的增删改查,业务逻辑的判断等。

3.是界面层view,是与用户交互的层次,往往只用于刷新显示界面

这些层次都有自己的使命,view层不能又进行业务逻辑的处理又进行界面显示刷新的操作,这样管理维护代码就清晰多了,那么随之问题就来了,但我业务逻辑层做了逻辑判断之后想要view层根据不同的业务进行ui显示时又该怎么做呢?这个就需要我们自定义异常类登场了。我们以简单密码校验为例:

我们只对密码进行校验,当登录时如果密码为123提示登录成功,否则提示失败

import java.util.Scanner;public class Login {public static void main(String[] args) {Scanner scan = new Scanner(System.in);String pw = scan.nextLine();if ("123".equals(pw)) {System.out.println("登录成功");}else{System.out.println("登录失败");}}}

这个是很直接的写法,逻辑判断与界面刷新显示都在view层去处理了,这种写法不是我们想要的,等到我们项目变大后你会发现view层做界面显示又做逻辑处理是多么的愚蠢。

下面我们用分层思想去实现该功能。

1.我们先自定义异常类 MyException


import java.io.PrintStream;
import java.io.PrintWriter;@SuppressWarnings("serial")
public class MyException extends Exception{/*** 重载构造函数*/public MyException() {super();}public MyException(String message, Throwable cause,boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}public MyException(String message, Throwable cause) {super(message, cause);}public MyException(String message) {super(message);}public MyException(Throwable cause) {super(cause);}/*** 重写父类的方法*/@Overridepublic String getMessage() {// TODO Auto-generated method stubreturn super.getMessage();}@Overridepublic String getLocalizedMessage() {// TODO Auto-generated method stubreturn super.getLocalizedMessage();}@Overridepublic synchronized Throwable getCause() {// TODO Auto-generated method stubreturn super.getCause();}@Overridepublic synchronized Throwable initCause(Throwable cause) {// TODO Auto-generated method stubreturn super.initCause(cause);}@Overridepublic String toString() {// TODO Auto-generated method stubreturn super.toString();}@Overridepublic void printStackTrace() {// TODO Auto-generated method stubsuper.printStackTrace();}@Overridepublic void printStackTrace(PrintStream s) {// TODO Auto-generated method stubsuper.printStackTrace(s);}@Overridepublic void printStackTrace(PrintWriter s) {// TODO Auto-generated method stubsuper.printStackTrace(s);}@Overridepublic synchronized Throwable fillInStackTrace() {// TODO Auto-generated method stubreturn super.fillInStackTrace();}@Overridepublic StackTraceElement[] getStackTrace() {// TODO Auto-generated method stubreturn super.getStackTrace();}@Overridepublic void setStackTrace(StackTraceElement[] stackTrace) {// TODO Auto-generated method stubsuper.setStackTrace(stackTrace);}@Overridepublic int hashCode() {// TODO Auto-generated method stubreturn super.hashCode();}@Overridepublic boolean equals(Object obj) {// TODO Auto-generated method stubreturn super.equals(obj);}@Overrideprotected Object clone() throws CloneNotSupportedException {// TODO Auto-generated method stubreturn super.clone();}@Overrideprotected void finalize() throws Throwable {// TODO Auto-generated method stubsuper.finalize();}}

然后写我的业务逻辑层LoginService

public class LoginService {//这里不能讲exception try catch ,将它抛出去让view层去捕获,再进行处理public void vertifyPw(String pw) throws MyException{if ("123".equals(pw)) {throw new MyException("登录成功");}else{throw new MyException("登录失败");}}}

最后刷新view

import java.util.Scanner;public class Login {public static void main(String[] args) {Scanner scan = new Scanner(System.in);String pw = scan.nextLine();LoginService ls = new LoginService();// 这里调用vertifyPw(),方法进行校验,根据不同的返回值做打印输出e.getMessage();try {ls.vertifyPw(pw);} catch (MyException e) {System.out.println(e.getMessage());}}}

我在注释中已对关键地方做了注解,看代码应该很容易能理解到自定义异常的好处了吧!


结语:不要叹气,你现在走的每一步都是为你昨天的选择买单,换句话说,这也叫担当!









http://chatgpt.dhexx.cn/article/0gYLm02h.shtml

相关文章

Java自定义异常

使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Excepition类即可 在程序当中自定义异常类,大体可以分成几个步骤: 1.创建自定义异常类 2.在方法中通过t…

JAVA 基础学习之异常机制

异常机制 1、概念 异常指程序运行过程中出现的非正常现象,例如用户输入错误、除数为零、需要处理的文件不存在、数组下标越界等。在Java的异常处理机制中,引进了很多用来描述和处理异常的类,称为异常类。 2、异常的分类 Throwable下面又派生…

【Java】自定义异常

自定义异常: java提供的异常类,不够我们使用,需要自己定义一些异常类 格式: public class XXException extends Exception|RuntimeException{ 添加一个空参数的构造方法 添加一个带异常信息的构造方法 } 注意: 1.自…

Java异常详解及自定义异常

我已经不用 try catch 处理异常了!太烦人了_51CTO博客_try catch处理什么异常 一、异常的概念 1.定义(什么是异常?) 异常是例外,是一个程序在执行期间发生的事件,它中断正在执行程序的正常指令流。软件开发…

哈夫曼树(带权路径长度+树的带权路径长度+哈夫曼树定义+构造哈夫曼树+哈夫曼树性质+哈夫曼编码+计算平均码长-这里指WPL)

带权路径长度 树的带权路径长度WPL 哈夫曼树 哈夫曼树构造 哈夫曼树性质 哈夫曼编码 固定长度编码 可变长编码 前缀编码 固定长度编码、可变长编码、前缀编码、哈夫曼编码 思维倒图 试题

哈夫曼树——【实例】利用3,6,8,12,5,7这六个值作为叶子结点的权,由该权值集合构造的哈夫曼树中带权路径长度之和为多少,该树的深度为多少。

利用3,6,8,12,5,7这六个值作为叶子结点的权,由该权值集合构造的哈夫曼树中带权路径长度之和为多少,该树的深度为多少。 基础知识 哈夫曼树是一种带权路径长度最短的二叉树,也称为最优…

哈夫曼树(最优二叉树:带权路径长度最短的树(度相同的情况下))

基本概念 1、结点的路径长度:两结点间间路径上的分支数 2、树的路径长度:从根结点到每一个结点的路径长度之和 3、结点的带权路径长度:从根结点到该结点之间的路径长度与该结点的权的乘积 4、树的带权路径长度:树中所有叶子结…

已知权值的哈夫曼树,求带权路径长度

转自牛客网 有权值分别为11,8,6,2,5的叶子结点生成一棵哈夫曼树,它的带权路径长度为_______。

哈夫曼树-创建,编码,解码,带权路径长度(含全部代码)

目录 主要函数 所选实例 创建哈夫曼树 步骤 【分析】 哈夫曼树结构 注意项 代码 创建哈夫曼树结果截图 编码 【分析】 代码 哈夫曼树编码结果截图 解码 【分析】 代码 哈夫曼树解码结果截图 计算带权路径长度 【分析】 代码 计算带权路径长度结果截图 全…

求哈夫曼的带权路径长度

【问题描述】 已知输入两行正整数,第二行正整数之间用空格键分开,请建立一个哈夫曼树,以输入的数字为叶节点,求这棵哈夫曼树的带权路径长度。 【输入形式】 首先第一行为输入正整数的个数,然后接下来的一行正整数&a…

构造哈夫曼树以及求哈夫曼编码、树的带权路径长度

我们先搞清楚这几个概念 构造哈夫曼树的方法 将每种字符出现的频率先收集起来放在最上方,然后选择两个频率最小的增加到图中,并将他们的和作为他们的父节点,增加到图中,在最上方删除选择的两个节点(4和2)&a…

哈夫曼树的构建与最小带权路径长度

注意:哈夫曼树并不唯一,但带权路径长度一定是相同的。 二叉树:每个结点最多含有两个子树的树称为二叉树。定理:对于具有n个叶子结点的哈夫曼树,共有2n-1个结点。 哈夫曼树介绍 1哈夫曼树的定义 哈夫曼(Huffman&…

创建哈夫曼树并求带权路径长度

创建哈夫曼树并求带权路径长度 【问题描述】根据给定的权重,构造哈夫曼树,输出其带权路径长度。 【输入形式】输入权重,空格作为分隔,回车结束,权重个数小于10。 【输出形式】哈夫曼树的带权路径长度。 【样例输入】5…

哈夫曼树(构建以及计算加权路径长度)

今天做远景的笔试题,遇到了这么一道题,求{11,8,6,5,2}构成的哈夫曼树的加权路径长度。 好长时间没看数据结构,居然忘记怎么求了,该死。 考完下百度,好多答案居然都是错的。或者是光有答案没有过程。在这里把哈夫曼树的…

哈夫曼树的构建、编码以及带权路径长计算

给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。 构造哈夫曼树的算…

哈夫曼树与带权路径长度

问题: 权值分别为从19,21,2,3,6,7,10,32的结点,构造一棵哈夫曼树,该树的带权路径长度是? 哈夫曼树的一个应用: 压缩字符串https://…

哈夫曼树 和 树的带权路径长度

树的带权路径长度(Weighted Path Length of Tree):定义为树中所有叶结点的带权路径长度之和。 结点的带权路径长度:结点到树根之间的路径长度与该结点上权的乘积。 哈夫曼树是一种带权路径长度最短的二叉树,也称为最优二叉树。 哈夫曼树构建…

哈夫曼树的带权路径长度的算法

计算方法: ①先对集合中的结点按照权值从小到大排。 ②选两个权值最小的结点,将它们的权值相加构成一个新结点,原来的这两个最小的结点是新结点的左右子结点。 ③在有序集合中将两个被加过的结点去掉,再把新的结点放入集合中排…

哈夫曼树结构和带权路径长度计算

什么是哈夫曼树呢? 哈夫曼树是一种带权路径长度最短的二叉树,也称为最优二叉树。下面用一幅图来说明。 它们的带权路径长度分别为: 图a: WPL5*27*22*213*254 图b: WPL5*32*37*213*148 可见,图b的带权路径长…