前言
简介
Java程序执行过程中我们发生错误或者意外情况,比如数组越界,除数为0,当然有时候还会有一些语法,逻辑错误之类的,这些导致程序的正常流程被中断或者无法运行的,统称为异常
。
一、异常有哪些?
java中通过Throwable类的子类描述不同的异常,异常是其子类的实例化对象,这其中Exception与Error尤为重要。
-
Error表示不可预见的严重问题,是不可查的,如内存不足、虚拟机崩溃等。它们通常
不能被处理
,程序设计者不能通过其代码所能改变的。 -
Exception我们可以通过程序本身处理这个异常,也是我们需要重点关注的。
这其中又分为两种:
1.非运行时异常(已检查异常):编译器会强制要求程序员进行处理,在编译时就会报错
。它们通常表示程序正常运行时可能会发生的错误,例如文件不存在或网络连接失败。
2.运行时异常(未检查异常RuntimeExceptions):编译器会不强制要求
程序员进行处理。但是它们通常表示程序中出现了严重的错误,如空指针引用或数组越界。通常情况下可以通过最好通过编写良好的代码来避免它们的发生。
以下是常遇到的几个异常:
异常 | explain |
---|---|
NullPointerException(空指针异常) | 当试图访问一个空对象的成员变量或方法时,会抛出该异常。 |
ArrayIndexOutOfBoundsException(数组越界异常) | 当试图访问一个不存在的数组元素时,会抛出该异常 |
ClassCastException(类型转换异常) | 当试图进行一种不合法的类型转换时,会抛出该异常 |
FileNotFoundException(文件不存在异常) | 当试图打开一个不存在的文件时,会抛出该异常 |
IOException(输入输出异常) | 当试图进行一些输入输出操作时发生错误时,会抛出该异常 |
IllegalArgumentException(非法参数异常) | 当传入一个非法参数时,会抛出该异常 |
NumberFormatException(数字格式化异常) | 当试图将一个不合法的字符串转换成数字时,会抛出该异常 |
ArithmeticException(算数运算异常) | 除以零或者整数溢出等情况,会抛出该异常 |
在编写代码时,应该针对各种异常情况进行充分的测试和处理,以确保程序的健壮性和可靠性。为此异常的处理就格外重要。试图想想你自己好不容易写了一个小程序,平时调试没问题,最后综合整理的适合发生错误了,直接心态爆炸。@-@。这时候,你会想,要是有个方法能帮我找到这个错误所在,让这个程序得以正常运行就好了。
二、异常的捕获和处理
1.捕获异常
这需要用到try…catch语句,具体格式见下:
try{
//可能出现的异常代码
}catch(异常类型1 变量名1){
//处理异常的方式
}catch(异常类型2 变量名2){
//处理异常的方式
}finally{
//一定会执行的代码
}
- try语句
1.在try中运行可能产生异常的语句,并且产生异常后,异常之后的代码不会执行
。
2.try语句后面可以有任意个
catch。
3.try语句中的所有异常都由后面的catch负责处理。 - catch语句
1.每个catch语句负责捕捉处理一些异常。
2.catch语句中可以通过定义的异常对象来获取异常信息
(这样你就可以找到where发生了异常,便于优化代码),常见的有
getMessage():返回该异常的详细描述的字符串;
printStackTrace():将异常事件的跟踪栈信息输出;
3.不能定义
永远达不到的catch语句,也就是说父类异常不能出现在子类异常的前面。 - finally语句
1.一个try语句中,finally的存在是可选
的,但是一旦存在,无论有无异常,finally都必将执行
。
2.finally是可以提供统一的善后处理,在进行下一步操作之前
,对程序状态进行统一的管理
。
3.finally通常用来清理资源或执行必要的终止操作,例如关闭文件、数据库连接(IO里面常用)等。
下面将通过一些例子来加强你对这些概念的理解
- 在try中运行可能产生异常的语句,并且产生异常后,
异常之后的代码不会执行
。
public class Text1{
public static void main(String[] args){
try{
System.out.println("程序开始执行");
int a;
a=100/0;//算术错误,除数不能为零
System.out.println("程序运行结束");
}catch(ArithmeticException e){
System.out.println("e.getMessage():"+e.getMessage());//返回该异常的详细描述的字符串;将异常事件的跟踪栈信息输出
e.printStackTrace();//将异常事件的跟踪栈信息输出
}
}
}
不能定义
永远达不到的catch语句,也就是说父类异常不能出现在子类异常的前面。
public class Text1{
public static void main(String[] args){
try{
System.out.println("程序开始执行");
int a;
a=100/0;
System.out.println("程序运行结束");
}catch(Exception e){
e.printStackTrace();
}catch(ArithmeticException e){
e.printStackTrace();
}
}
}
这么做就错了哦,Exception是所有exception的父类,这个例子是想提醒你要注意catch异常的顺序(^-^)
请看看下面这一串代码,看看他将输出什么;
public class Text1{
public static void main(String[] args){
System.out.println(txt());
}
public static int txt(){
try{
int a=100/0;
return 1;
}catch(Exception e){
return 2;
}finally{
return 3;
}
}
}
你答对了吗???如果错了请再去看看finally语句第二条@-@。
2.抛出异常
- 上抛异常(throws)它的意思是在方法内部捕获异常后,将异常抛出到调用该方法的上一层调用者中进行处理,如果不做处理将一直上抛到main方法上,直到被main方法或JVM捕获和处理,如果一直不做处理,程序将终止运行。需要注意的是上抛异常,只是把问题抛给了上一级,并没有解决这个异常。此外throws后面可以更多个异常类名用逗号隔开。
- throw用于抛出异常对象,每次只能抛出一个,后面接的是异常对象名,并且throw语句一旦执行,它后面的代码都
不会被执行
(常用于自定义异常)。
区别:
1.throws的放在方法括号后面,而throw用在方法体内
2.throws 表示出现异常的一种可能性,并不一定会发生这些异常;而执行throw则一定抛出了某个异常对象。
老规矩还是用代码展示一下:
public class Text1{
public static void main(String[] args) throws ArrayIndexOutOfBoundsException{
int [] arr=new int[10];
arr[11]=10;
}
}
这里数组越界了,该异常从mian()方法抛到JVM,JVM打印跟踪信息栈后程序运行结束。
结果如图所示:
三、自定义异常
- 自定义异常是指根据程序设计者的需求,自行定义的一种异常类型。通过继承现有的异常类(一般为Exception类或者RuntimeException类)。程序员可以创建一个新的异常类,并定义这个异常类的特定行为和属性。自定义异常通常用于处理程序中特定的错误或警告情况,以便更好地控制程序的流程和错误信息的输出。
-注意:
1.自定义异常必须手动throw抛出;
2.在异常类中至少定义两个
构造方法,一个是无参的构造方法,另一个是带String对象参数的构造方法,这个对象将作为该异常对象的描述信息。
为了便于你的理解见下代码:
import java.util.*;
public class Text1{
public static void main(String[] args) {
System.out.println("请输入您的年龄:");
Scanner in=new Scanner(System.in);
int age=in.nextInt();
if(age<0){
try{
throw new MyException("年龄不能为负数");
}catch(MyException e){
e.printStackTrace();
System.out.println(e.getMessage());
System.out.println(e.getMyMessage());
}
}
}
}
class MyException extends Exception{
public MyException(){
}
public MyException(String er){
super(er);//调用Throwable中的getMessage()
}
public String getMyMessage(){
String er="自定义方法:年龄不能为负数";
return er;
}
}
注意一下super(er)为调用Throwable中的getMessage(),该方法被定义为final
方法,无法被子类重写或覆盖,但可以自己定义一个新的不重名的方法如getMyMessage()。
总结
以上就是今天要讲的内容,本文简单介绍了异常的定义,异常的捕获和处理,以及自定义异常。希望对你有所帮助,如有不对,请指正!!!^ - ^