一.、异常介绍
二、自定义异常使用符合情况
三、throws与throw使用
四、throws、throw与try catch联合使用
五、小结
一、异常介绍:
异常就是程序出现了不正常的情况,包括编译出错和运行出错造成的异常。
如果程序出现了问题,我们没有做出任何处理:
①、最终JVM会做默认的处理,即把异常的名称、异常原因级异常出现的位置等信息输出在了控制台。
②、但是从程序出现问题的位置开始,剩余部分的代码将不会再运行,且异常提示是基于JVM内部已经规定的异常情况。
示例:
import java.util.Scanner;
public class Test{
public static void main(String[] args) {
System.out.println("开始");
int[] arr = {1, 2, 3};
Scanner input = new Scanner(System.in);
System.out.println("现在请输入你要查找的数组中的数据的索引值:");
int i = input.nextInt();
method(i,arr);
System.out.println("查询完成!");
}
public static void method(int i, int[] arr){
System.out.println("此索引条件下的数组数据为:"+arr[i]);
}
}
开始
现在请输入你要查找的数组中的数据的索引值:
3
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at NomalAPI.Test.method(ExceptionSolve.java:102)
at NomalAPI.Test.main(ExceptionSolve.java:96)
没有人为的介入,JVM在遇到异常程序语句会抛出符合这种情况的异常提示和详细信息,但不会继续执行异常语句之后的其他语句,程序中断。
二、自定义异常使用符合情况:
并非所有的情况,我们都有权限去做异常处理,而且为了让异常提示更加友好易懂并且符合我们当前情况下JVM能够做出相应的异常提示,我们可以选择自定义异常。
三、throws与throw使用:
为了达到自定义异常的效果,我们可以考虑使用throws和throw。
throws用在方法声明后,跟的是异常类名,表示抛出异常,由该方法的调用者来处理,也代表有出现异常的可能性,但并不一定会发生这些异常。
throw与之不同的是,用在方法体内,跟的是异常对象名,表示抛出异常,由方法体内的语句处理,执行throw则表示一定抛出某种异常。
示例:
import java.util.Scanner;
public class IdentiExcept extends Exception { //自定义异常,两个构造函数,接收指定的详细消息以构造新的异常。
public IdentiExcept() {
}
public IdentiExcept(String message) {
super(message); //点击super 再按下Ctrl+B,即可查看super的详细内容,发现message的内容最终交给了throwable的私有变量detailmessage。替代成为异常的详细信息
}
}
class Temper {
public void fill(int num) throws IdentiExcept { //throws用类声明之后,代表着可能发生异常的情况,所以,接下来的内容,我们采用条件语句
if(num<35.5 ||num>37.5){ //自定义抛出异常的条件
throw new IdentiExcept("可能是发烧了,要尽快去医院看医生哦!"); //throw出现即代表抛出某种异常,我们使用匿名函数直接调用自定义异常类,将自定义提示信息赋给message
}else{
System.out.println("体温正常!");
}
}
}
class Demot{ //该文件的测试类
public static void main(String[] args) throws IdentiExcept {
Scanner input=new Scanner(System.in);
System.out.println("请输入测试的体温:");
int tem= input.nextInt();
Temper t=new Temper(); //实例化
t.fill(tem); //调用Temper的方法
System.out.println("本次检测完成!");
}
}
//情况一:
请输入测试的体温:
38
Exception in thread "main" NomalAPI.IdentiExcept: 可能是发烧了,要尽快去医院看医生哦!
at NomalAPI.Temper.fill(IdentiExcept.java:66)
at NomalAPI.Demot.main(IdentiExcept.java:82)
//情况二:
请输入测试的体温:
36
体温正常!
本次检测完成!
总结,在这类自定义异常的情况下,我们主要分三个步骤来做:
①、自定义类,继承异常类(Exception),在类中定义构造函数,其中包括
public IdentiExcept(String message) {
super(message);
}
以便我们将自定义信息传入并输出在控制台
②、自定义异常判断类,其中定义可以进行异常判断的成员方法,该方法需要追接throws自定义的
用来继承异常类(Exception)的类名,即第一步的类。
用条件语句区分出异常情况,而一旦满足异常情况,则执行throw语句,这也正好满足throw一
定抛出异常的说法。而抛出的可以是匿名对象,当然可以先new一个实例对象,然后再用
throw抛出,效果是一样的。
③、建立程序的入口。正常定义和正常调用判断异常的类中的方法,但是由于我们有调用异常判断
类的情况,所以这个入口类同样会被要求throws自定义的继承了异常类的类名。
四、throws、throw与try catch联合使用:
通过上方的throws和throw的使用,我们已经可以在满足自己要求的情况下自定义异常,但是,一旦碰到异常,我们所执行的异常就会导致程序中断,那应该怎么解决这类问题呢?这里就不得不提起try catch的使用了。
try…catch…的使用,try中是可能出现异常的程序语句,而catch中的是出现异常的处理办法。这种方法还保证了在跳过异常提示之后,剩余部分的代码依旧可以执行。
示例:
import java.util.Scanner;
public class IdentiExcept extends Exception { //自定义异常,两个构造函数,接收指定的详细消息以构造新的异常。
public IdentiExcept() {
}
public IdentiExcept(String message) {
super(message); //点击super 再按下Ctrl+B,即可查看super的详细内容,发现message的内容最终交给了throwable的私有变量detailmessage。替代成为异常的详细信息
}
}
class Temper {
public void fill(int num) throws IdentiExcept { //throws用类声明之后,代表着可能发生异常的情况,所以,接下来的内容,我们采用条件语句
if(num<35.5 ||num>37.5){ //自定义抛出异常的条件
throw new IdentiExcept("可能是发烧了,要尽快去医院看医生哦!"); //throw出现即代表抛出某种异常,我们使用匿名函数直接调用自定义异常类,将自定义提示信息赋给message
}else{
System.out.println("体温正常!");
}
}
}
class Demot{ //该文件的测试类
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("请输入测试的体温:");
int tem= input.nextInt();
Temper t=new Temper(); //实例化
try{ //使用try catch可以让程序在出现异常之后能够继续执行最后的输出语句
t.fill(tem); //try语句是调用可能造成异常的类的方法
}catch(IdentiExcept e){ //catch括号里面的对象e会接收到上方Temper类throw出来的内容,即IdentiExcept e=new IdentiExcept("可能是发烧了,要尽快去医院看医生哦!")
e.printStackTrace(); //public void printStackTrace()这是Throwable类中的成员方法,而Throwable是java中所有错误和异常(Exception)的超类,又IdentiExcept继承Exception,
}
System.out.println("本次检测完成!");
}
}
//情况一:
请输入测试的体温:
38
NomalAPI.IdentiExcept: 可能是发烧了,要尽快去医院看医生哦!
at NomalAPI.Temper.fill(IdentiExcept.java:22)
at NomalAPI.Demot.main(IdentiExcept.java:40)
本次检测完成!
//情况二:
请输入测试的体温:
36
体温正常!
本次检测完成!
整体的程序设计的方法与上面的throws和throw没有太大的区别。
最大的区别在于,第三步程序入口中,t.fill(tem)方法调用放在了try语句中,因为只有在方法调用的时候,才能出现异常的判断,才有可能出现异常,满足了try语句内容的说法。
而catch主要用于处理异常,我们在②中抛出虚拟对象,因此在catch()中创建对象,在语句中,用实例调用异常类的printStackTrace()方法,在控制台输出我们自定义的异常信息。
五、小结:
就本人看来,throws与throw对于整个程序最直观的影响,就是使提示信息更加人性化,方便看懂异常出现的原因。而try catch则可以帮我们避免一些因为出现一些小问题而造成程序中断的意外,可以说相当的实用了。
在IDEA中写程序,会有错误提示,就是一个小小的红色💡,如果大家不知道怎么修改或调整代码,可以直接试用它推荐的修改方法。
当然,这里举的一些例子都是最简单的,想要在复杂大型的项目中处理问题,肯定还需要继续学习。
如果文章内容存在问题,欢迎大家指正!!