Day39--自定义异常及小结
Day39--自定义异常及小结
自定义异常
- 使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
- 在程序中使用自定义异常类,大体可分为以下几个步骤:
- 创建自定义异常类。
- 在方法中通过throw关键字抛出异常对象。
- 如果在当前抛出异常的方法中处理异常,可以使用try - catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
- 在出现异常方法的调用者中捕获并处理异常。
示例:
在demo02中,创建异常类Myexception类。它是Exception的子类。创建私有的成员变量----整数detail。创建有参构造器 参数:int a;方法体: this.detail = a; 重写toString方法
package com.liu.exception.demo02;
//自定义异常类
public class Myexception extends Exception {
//传递数字>10,异常
private int detail;
public Myexception(int a) {
this.detail = a;
}
//toString;异常的打印信息 Alt+Insert----toString
@Override
public String toString() {
return "Myexception{" +
"detail=" + detail +
'}';
}
}
写完异常类之后,我们要写测试类,测试我们写的异常
写可能会存在异常的方法
在Test类里面,创建静态方法test,参数int a,声明异常Myexception。方法体:输出"传递的参数为:"+a;如果a大于10则抛出异常;否则输出ok。 在main方法里面,用try-catch,包裹test(101),异常类型:Myexception,输出:"Myexception--->"+e
package com.liu.exception.demo02;
public class Test {
//可能会存在异常的方法
static void test(int a) throws Myexception {
System.out.println("传递的参数为:"+a);
if(a>10){
throw new Myexception(a);//抛出
}else {
System.out.println("OK");
}
}
public static void main(String[] args) {
try {
test(101);
} catch (Myexception e) {
System.out.println("Myexception--->"+e);
}
}
}
传递的参数为:101
Myexception--->Myexception{detail=101}
在 Java 程序中,程序的执行是从main方法开始的。
- 程序启动
- 当你运行这个 Java 程序时,Java 虚拟机(JVM)会首先查找
main方法作为程序的入口点。
- 当你运行这个 Java 程序时,Java 虚拟机(JVM)会首先查找
main方法中的操作- 在这个
main方法中,它调用了test(101)方法。 - 当
main方法执行到test(101)这一行时,程序的控制流会转移到test方法。
- 在这个
test方法的执行test方法被调用后,它会执行其中的逻辑。在这个例子中,由于a = 101,a>10条件成立,test方法会抛出一个Myexception异常。- 因为
test方法通过throws Myexception声明了它可能抛出这个异常,所以当异常被抛出时,程序的控制流会返回到main方法中调用test方法的地方。
- 异常处理
- 在
main方法中,有一个try - catch块来捕获Myexception异常。当test方法抛出Myexception时,catch块会捕获这个异常并执行其中的逻辑,即打印"Myexception--->"和异常信息。
- 在
以下是对这段代码运行全过程的详细讲解:
1. 代码整体结构与类的关系
这段代码包含了两个类:Test类和Myexception类。Myexception类是一个自定义异常类,它继承自Exception类,用于表示特定业务场景下的异常情况。Test类中定义了一个静态方法test以及包含了main方法用于测试调用test方法的逻辑处理。
2. Myexception类解析
- 成员变量:
在Myexception类中,定义了一个私有的整数类型成员变量detail,这个变量用于存储一些和异常相关的详细信息,比如在这个例子中,它用来保存传入的整数参数值,以便后续通过重写toString方法展示更详细的异常内容。 - 构造器:
有一个带有int类型参数a的构造器,在构造器内部,通过this.detail = a;语句将传入的参数值赋值给detail变量,这样当创建Myexception异常对象时,就能把相关的信息存储到对象内部了。 - 重写
toString方法:
重写了toString方法,该方法原本在Object类中定义,用于返回对象的字符串表示形式。在这里重写后,返回的字符串格式为"Myexception{" + "detail=" + detail + '}',这样当输出Myexception对象时,会按照这个自定义的格式展示异常对象中包含的detail信息,使得异常信息更加直观、明确,方便开发人员了解异常的具体情况。
3. Test类中的test静态方法解析
- 方法声明与异常声明:
test方法被定义为静态方法,接收一个int类型的参数a,并且声明抛出Myexception异常。这意味着在方法内部如果出现符合特定条件的情况,就会抛出这个自定义的异常,让调用者去进行相应的异常处理。 - 方法体逻辑:
- 首先,通过
System.out.println("传递的参数为:" + a);语句输出传入的参数值,这样可以在控制台看到传入test方法的具体参数是什么。 - 接着,使用
if (a > 10)条件判断语句来检查参数a的值是否大于10。如果大于10,就通过throw new Myexception(a);语句抛出一个Myexception异常对象,并且把当前的参数值a传递给异常对象的构造器,使得异常对象能够保存这个相关信息(存储在detail变量中)。 - 如果参数
a不大于10(即a <= 10),则执行System.out.println("OK");语句,输出OK表示参数满足一定的正常条件范围。
- 首先,通过
4. main方法中的异常处理逻辑解析
try-catch结构:
在main方法中,使用了try-catch语句来调用test方法并处理可能抛出的异常。try块里面通过test(101);调用test方法并传入参数101,由于101大于10,在test方法内部会抛出Myexception异常。- 异常捕获与处理:
当test方法抛出Myexception异常后,程序流程会立即跳转到对应的catch块中进行处理。在catch (Myexception e)中,参数e就是捕获到的Myexception异常对象,然后通过System.out.println("Myexception--->" + e);语句输出异常相关的信息,这里会隐式地调用e的toString方法(因为重写了toString方法,所以会按照自定义的格式展示异常信息),最终在控制台会输出类似Myexception--->Myexception{detail=101}这样的内容,清晰地显示出了异常的具体情况,也就是展示出了传入test方法的参数值,这个值作为异常的详细信息被保存并展示了出来。
5. 代码运行步骤总结
- 程序从
main方法开始执行。 - 进入
try块,调用test(101),程序跳转到test静态方法中执行。 - 在
test方法中,先输出传递的参数为:101,然后判断101大于10,所以抛出Myexception异常,同时将101作为参数传递给Myexception异常类的构造器创建异常对象。 - 由于抛出了异常,
test方法立即停止执行后面的代码(不会输出OK了),程序流程跳转到main方法的catch块中。 - 在
catch块中,捕获到Myexception异常对象,通过输出语句结合重写的toString方法,输出Myexception--->Myexception{detail=101},展示出异常的详细情况,至此完成了整个代码的运行过程以及异常处理逻辑。
总的来说,这段代码展示了自定义异常的创建、抛出以及在try-catch结构中进行捕获和处理的完整流程,通过自定义异常可以更精准地处理业务逻辑中出现的特定错误情况哦。
实际应用中的经验总结
- 处理运行时异常时,采用逻辑去合理规避同时辅助try - catch处理
- 在多重catch块后面,可以加一个catch (Exception)来处理可能会被遗漏的异常
- 对于不确定的代码,也可以加上try - catch,处理潜在的异常
- 尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出
- 具体如何处理异常,要根据不同的业务需求和异常类型去决定
- 尽量添加finally语句块去释放占用的资源(类似Scanner)

浙公网安备 33010602011771号