Java – 异常Exception
简介
异常分为编译时异常和运行时异常
编译时异常是除了RuntimeException和他的子类,其他都是编译时异常,编译阶段需要进行处理,作用在于提醒程序员
运行时异常是RuntimeException本身和所有子类,都是运行时异常,编译阶段不报错,是程序运行时出现的。
try...catch 捕获异常
使用 try 语法格式
try {
可能出现的异常的代码;
}catch (异常类名 变量名){
异常的处理代码;
}
当代码出现异常时,可以让程序继续往下执行
注意:catch() 中传入的参数必须是可能异常的代码所报出的对应异常类或它的父类,否则catch() 无法成功捕抓异常。
比如,数组索引越界的代码,必须要传入ArrayIndexOutOfBoundsException 异常,如果传入的是 StringIndexOutOfBoundsException 那catch() 是无法捕获的
IDEA 中,可以通过 Ctrl + Alt + T 快捷键唤出快速代码补充功能填充 try catch方法体
try catch 情况解析
try中没有异常会如何?
当 try 中的代码没有异常,会把try中的代码全部执行,跳过 catch() 直接继续往下面执行。
try中遇到多个异常会如何?
当 try 中的代码,遇到第一个异常时,就会按照异常类型寻找对应的 catch() 调用 catch 代码,如果 catch() 中只包含一个异常处理,那么,Java会在调用 try 中第一个异常后,就不再执行 try 里面的其它代码了
int[] nums = {1, 2, 3, 4, 5};
try {
System.out.println(nums[10]); // 这里出现了越界异常,会调用 catch
System.out.println(2/0); // 这里不会执行
}catch (StringIndexOutOfBoundsException e){
System.out.println("越界了");
}
System.out.println("继续执行"); // 这里会继续执行
catch 中可以使用指定异常的父类,但前提是父类必须往后定义,否则,父类接收了异常后,下面的 catch 异常子类将不会被接收,同时也会报编译错误
int[] nums = {1, 2, 3, 4, 5};
try {
System.out.println(nums[10]);
System.out.println(2/0);
}catch (ArrayIndexOutOfBoundsException | ArithmeticException e){
System.out.println("要么越界了,要么除数为0了");
}catch (Exception e){
// 定义 所有异常的父类 Exception 可以捕获任意异常,但必须排在最后面,否则所有子类都接收不到异常
}
在JDK7 之后,可以通过共享 catch 达到一个 catch 捕获多个异常
int[] nums = {1, 2, 3, 4, 5};
try {
System.out.println(nums[10]);
System.out.println(2/0);
}catch (ArrayIndexOutOfBoundsException | ArithmeticException e){
System.out.println("要么越界了,要么除数为0了");
}
System.out.println("继续执行");
try 中的异常没有被捕获?
会被系统以默认的异常处理方式处理,try .. catch 没有意义,最终还是会交给虚拟机进行处理
int[] nums = {1, 2, 3, 4, 5};
try {
System.out.println(nums[10]); // 触发异常,但不会走到NullPointerException 异常,于是会调用Java默认异常处理,并停止执行
System.out.println(2/0);
}catch (NullPointerException e){
System.out.println("空指针了");
}
System.out.println("不会执行");
try遇到异常,try里的其它代码还执行吗?
如果try遇到异常,会在 catch 中寻找对应的异常处理方法,try 异常代码后面的代码将不再执行,如果找不到对应的 catch 依然会交给虚拟机进行默认异常处理。
异常常用方法
getMessage 详细消息
方法名:public String getMessage()
在 catch 中,如果捕获了异常,可以使用 e.getMessage() 方法获得简短的错误信息
try {
System.out.println(nums[10]);
System.out.println(2/0);
}catch (ArrayIndexOutOfBoundsException e){
String message = e.getMessage();
System.out.println(message);
}
toString 简短描述
方法名:public String toString()
在 catch 中,如果捕获了异常,可以使用 e.toString() 方法获得相对详细的错误信息
try {
System.out.println(nums[10]);
System.out.println(2/0);
}catch (ArrayIndexOutOfBoundsException e){
String message = e.toSting();
System.out.println(message);
}
printStackTrace 打印错误
方法名:public void printStackTrace()
在 catch 中,如果捕获了异常,可以使用 e.printStackTrace() 以报错红节的形式打印异常信息
try {
System.out.println(nums[10]);
System.out.println(2/0);
}catch (ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}
finally 异常后处理
finally{} 代码块,是指当使用 try..catch 时,try中被抛出了异常时,try 中的其它代码将不再进行执行,而是直接跳到 catch 代码块中。
那如果有某些情况下,当不管出现什么问题,都必须要对错误代码中的对象进行处理时(如文件读取错误时,也必须关闭文件读取),我们可以把代码写到 finally 代码块中。
finally 代码块一定会执行,除非JVM被关闭
try {
// 出异常时会跳到 catch 代码块执行,其后的代码不再执行
}catch (){
// 出异常时会被调用
}finally {
// 不管有没有出异常,都一定会执行
}
抛出异常
throws
throws 是用于定义方法体中是否包含抛出异常的行为,如果一个方法体中的代码存在 try catch 且里面包含异常抛出的情况,需要在方法定义处,定义抛出的异常。
// 如果方法体内出现 抛出异常的行为,那么可以在 方法定义处,定义可能会抛出异常的异常点
public void getMax(int[] i) throws NullPointerException,ArrayIndexOutOfBoundsException{
// 方法体内出现 抛出异常的行为
if (i == null){
throw new NullPointerException();
}
// // 方法体内出现 抛出异常的行为
if (i.length < 1){
throw new ArrayIndexOutOfBoundsException();
}
}
注意:如果是运行时的异常,可以不需要在方法定义中声明,但是如果是编译时的异常,那么必须要在方法定义中声明.
我们举个例子,SimpleDateFormat 类中,有一个parse方法,是通过一定的格式对日期进行解析,在parse方法体中,存在一个编译时异常抛出,所以在调用 parse 方法时,我们必须要声明异常,否则会报错不通过编译
public Date parse(String source) throws ParseException
{
ParsePosition pos = new ParsePosition(0);
Date result = parse(source, pos);
if (pos.index == 0)
throw new ParseException("Unparseable date: \"" + source + "\"" ,
pos.errorIndex);
return result;
}
可以使用 try..catch 方式
try {
sdf.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
也可以通过在调用方法签名中声明异常
public static void main(String[] args) throws ParseException
throw
throw 是用于抛出异常行为的方法,当某些操作会出现问题时,可以使用 throw 语法抛出异常,把异常扔回调用者处理
if(i == null)
{
throw new NullPointerException();
}
这样调用者就会接收到这个异常信息。
自定义异常
Java 中会提供各种异常的类,供我们使用,但是在某些时候,我们的很多操作出现异常,Java的异常类又不能完全满足我们对于这个异常的描述时,我们可以通过创建自定义异常来对某一类异常进行描述。
定义一个自定义异常类需要满足4点
1.定义异常类
异常本身只是一个没有过多操作方法的类,我们使用异常类,本身只是为了通过异常类的类名见名知意。
因此,定义异常类,类的名称必须清楚且见名知意即可
2.写继承关系
异常类分两种,一种是运行时异常,另一种是编译时异常,如果我们的异常定义初衷是为了防止在运行的过程中,输入或传入非法数据引起的报错,那么我们定义异常类的时候,应当继承 RuntimeException
如果,我们认为,这个方法在编译时,就有可能出现语法错误或非常容易出错的情况下,我们可以把异常类声明为编译异常,异常类应当继承 Exception
类,同时,方法定义签名上必须声明 throws 异常名
3.空参构造
创建一个空参构造。可使用 Alt + Insert 自动创建构造
4.带参构造
创建一个带参构造。可使用 Alt + Insert 自动创建构造
共有 0 条评论