异常的继承机制
所有的异常类都是Throwable的子类
Error描述的是Java运行系统内部错误及资源耗尽情况下的错误
只要不是程序员捕获的异常,最终都会被默认异常处理程序处理,默认处理程序会打印异常的类型和异常发生时所处的堆栈,并且立即终止程序。
常见异常
public static void main(String[] args) {
int x=0;
int y=0;
int m=x/y;//除数作为0的情况会产生java.lang.ArithmeticException
int arr[]={1,2,3};
System.out.println(arr[3]);//ArrayIndexOutOfBoundsException
boolean b[]={true,true};
int array[]={1,2};
System.arraycopy(array,0,b,0,1);
//数组存入与声明不符,属于RuntimeExceptinon的子类,ArrayStoreException
}
异常处理语法
try{ 有可能出现异常的语句 ; }
[catch (异常类 对象) { } ... ]
[finally { 异常的出口 }]
组合方式有try{}catch{}
try{}finally{}
try{} catch{} finally{}
其中try语句中放可能出现多重异常的语句,并且try语句块不能单独出现,必须与finally或catch块结合
catch块可以有多个用来捕获多个异常,捕获的异常类的实例声明放在catch的圆括号中,若不能处理异常,则可在花括号中利用throw关键字手工抛出;捕获多个异常时遵循先子类后父类的原则,否则编译会报错
finally语句块不一定必须存在,但是若有finally块,finally块中的语句会先于return语句执行(return语句失效)
在以下情况除外,finally语句块一定执行:
1.在finally语句之前执行了System.exit();
2.在finally语句块之前出现线程死亡或未知错误(断电,硬件损坏等)
加入异常处理的代码,当异常发生时,程序不会因为异常而中断
public static void main(String[] args) {
System.out.println("1.计算开始前");
try {
System.out.println("2.计算开始" + 2 / 0);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("不管是否出现异常都会打印");
}
{
System.out.println("3.计算结束");
}
}
输出结果:
printStackTrace()
方法的功能是打印异常信息,也同样是System输出流,因此与方法体或代码块的输出语句顺序不确定
throws关键字
产生异常时,暂时不想处理可以在方法签名上声明异常throws 异常类名
抛出的异常谁调用谁处理:在调用有异常的方法时,必须用try catch块处理异常或是继续用throws关键字在当前方法签名上声明异常,若是一直向上抛出,直到程序的入口,main方法中,会由JVM处理异常,即遇见异常就终止程序.throws声明的异常不能比catch块捕获的异常类型范围大,否则编译出错
public static int calcu(int x, int y) throws Exception {
System.out.println("1.开始计算");
int res = 0;
try {
res = x / y;
}catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("计算结束");
}
return res;
}
throw关键字
若需在程序中手工自行抛出异常,则是由throw关键字,throw语句可以单独使用,用于方法体内部,throw抛出的不是异常类,而是异常实例(new的对象)
不检测异常与检测异常:
不检测异常:对Error类或其子类和RuntimeException类或其子类就不用捕获或抛出.其他的异常类就是检查类异常
使用throw抛出不检查异常时,不需要再方法签名处声明方法可能抛出的异常类型,而抛出的是检查异常时,必须在方法头部声明异常类型,该方法的调用者也必须检查处理抛出的异常或继续声明异常
public static void arrException() {
throw new NullPointerException("自行抛出异常");//不检测异常不需用throws声明异常
}
public static void main(String[] args) {
try {//没有声明的异常也可以抓捕异常
arrException();
} catch (Exception e) {
System.out.println(e);
}
}
异常处理的标准格式:
public class ExceptionTest2 {
public static void main(String[] args) {
try {
Execeptions.calcu(2, 2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Execeptions {
public static int calcu(int x, int y) {
System.out.println("1.开始计算");
int res = 0;
try {
res = x / y;
}
//可加可不加,throw与throws不一定非需要同时出现
catch (Exception e) {
throw e;
}
finally {
System.out.println("计算结束");
}
return res;
}
}
自定义异常类
通过继承:Exception或RuntimeException两种方式实现自定义异常类
public class AddExceptionTest {
public static void main(String[] args){
int a = 2;
int b = 3;
if (a + b == 5) {
try {
throw new AddException("相加之和为5");
} catch (AddException e) {
e.printStackTrace();
}
}
}
}