Java学习笔记-6
一、异常
- 异常本身是一个类,产生异常即创建并抛出异常对象,产生异常的方法若未加处理措施则抛给main方法,再从main方法抛给JVM处理,JVM会进行中断处理并打印异常类型
- Throwable有两个子类Error和Exception,其中Exception是可以解决的异常(通过throws或try…catch解决),Error则必须修改源码
二、异常处理
1.throw
在指定方法中抛出指定的异常,必须写在方法内部
throw new xxxException("异常产生的原因");
对方法传递过来的参数必须先进行合法性校验,比如参数是数组却传过来了null就要抛出空指针异常(NullPointerException)
注:NullPointerException是一个运行期异常,不需要自己处理,交给JVM处理即可,但对于编译异常就必须通过throws或是用try…catch处理
Objects类自带一个检测是否为空指针的方法requireNonNull,可以直接使用
2.throws
在方法声明时使用
修饰符 返回值类型 方法名(参数列表) throws AAAException,BBBException…
{
throw new AAAException("产生原因");
throw new BBBException("产生原因");
}
1.throws后需要声明方法内抛出的全部异常对象(有子父类关系则只用声明父类)
2.调用了抛出异常的方法就必须通过throws交给调用者->JVM去处理,或是用try…catch自己处理(即throws等需要在方法声明处与调用处声明两次)
3.try…catch
可执行后续代码
try{
可能产生异常的代码
}
catch(异常类名 变量名){
对异常对象的处理(一般会选择记录到日志)
}
...
//可以有多个catch,但子类异常变量必须在前面
执行catch后会继续执行后续代码(但是try中产生异常后的代码不会执行),而throws交给JVM会进行中断处理
4.Throwable中的三个异常处理方法
1.getMessage() 返回Throwable的简短描述
2.toString() 返回Throwable的详细消息字符串
3.printStackTrace() 打印异常对象
5.finally
放在catch代码块后面,不管是否有异常都会执行
finally一般用于资源释放/回收,注意finally中的return一定会执行,为了避免最好不要在finally中返回
6.子父类异常
父类方法声明抛出的异常子类在重写时只能抛出相同异常或其子类异常或不抛出异常
父类方法不抛出异常子类重写时只能捕获不能抛出(即只能try…catch)
三、自定义异常类
public class XXXException extends Exception 或 RuntimeException{
一个空参数构造方法 super();
一个带异常信息构造方法
}
//继承Exception为编译期异常,必须throws抛出或自己处理(try...catch)
//继承RuntimeException为运行期异常,无需处理,自动交给JVM
package day5;
public class RegisterException extends Exception{
RegisterException()
{
super();
}
RegisterException(String message)
{
super(message);
}
}
package day5;
import java.util.*;
public class day5 {
public static int getElement(int[] arr, int index) throws NullPointerException,ArrayIndexOutOfBoundsException
{
if(arr == null) {
throw new NullPointerException("数组为空");
}
if(index < 0 || index > arr.length - 1)
{
throw new ArrayIndexOutOfBoundsException("索引值越界");
}
return arr[index];
}
public static void main(String[] args) throws RegisterException{
// int[] arr1 = null;
// getElement(arr1,4);
int[] arr2 = {1,2,3};
try
{
getElement(arr2,5);
}
catch(NullPointerException n)
{
System.out.println("数组为空");
n.printStackTrace();
}
catch(ArrayIndexOutOfBoundsException a)
{
System.out.println("索引值越界");
a.printStackTrace();
}
finally
{
System.out.println("资源释放");
}
System.out.println("后续代码正常执行");
System.out.println();
//自定义异常类
Scanner sc = new Scanner(System.in);
System.out.println("请输入姓名:");
String input = sc.next();
try
{
check(input);
}
catch(RegisterException e)
{
System.out.println("异常成功捕获并处理,异常详情:");
e.printStackTrace();
}
}
static String[] name = {"张三","李四"};
public static void check(String s) throws RegisterException
{
for(String n : name)
{
if(s.equals(n))
{
throw new RegisterException("该用户已存在!");
}
}
System.out.println("注册成功!");
}
}