什么是异常
异常:软件在编译或者运行过程中,因为一些原因(BUG、用户使用不当、代码处理不当),而引起的程序奔溃的现象,叫做异常。
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error;如果你用System.out.println(11/0),那么你是因为你用0做了除数,会抛出 java.lang.ArithmeticException 的异常。
异常发生的原因有很多,通常包含以下几大类:
用户输入了非法数据。
要打开的文件不存在。
网络通信时连接中断,或者JVM内存溢出。
异常的继承体系结构
所有的异常类是从 java.lang.Exception 类继承的子类。
Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。
Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。
Error 用来指示运行时环境发生的错误。
例如,JVM 内存溢出。一般地,程序不会从错误中恢复。
异常类有两个主要的子类:IOException 类和 RuntimeException 类。
捕获异常
使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。
try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下:
public static void testEx(int num1, int num2) {
int res;
try {
res = num1 / num2;
System.out.println(res);
} catch (Exception e) {//当参数传入num2为0时会触发除零的异常,从而执行catch代码块中的代码
e.printStackTrace();//打印异常信息的执行栈(异常具体出现再第几行)
}
}
注意:try去抓捕异常,如果没有抓到异常,代码正常执行(不会执行catch块中代码)
如果抓捕到异常,则进入对应的catch块。
多异常的处理
try {
// 可能存在了异常的代码
// xxxx
} catch(ArithmeticException e) { // ArithmeticException e = new ArithmeticException();
// 说明代码处理ArithmeticException
// 在这儿处理这个异常!!!
} catch(NullPointerException e) {
System.out.println("处理空指针异常");
// 在这儿处理这个异常!!!
}
多异常处理是有多个catch代码块,触发了什么异常就执行什么异常的catch代码块
向上抛出异常
函数可以不处理异常,交给上层函数处理
public class TestEx {
public static void main(String[] args) {
try {
testEx(5,0);//main函数调用testEx,可以抓捕处理其抛出的异常或继续向上抛出
} catch (Exception e) {
e.printStackTrace();
}
}
public static void testEx(int num1, int num2) throws Exception{//不在函数中处理可能发生的异常,将异常向上抛出
int res;
res = num1 / num2;
System.out.println(res);
}
}
自定义异常
创建自定义异常类,类名为XxxxException是潜规则,然后继承RuntimeException类,重写五个构造函数和序列号
public class MyException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 3726576137665539799L;
public MyException() {
super();
// TODO Auto-generated constructor stub
}
public MyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public MyException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public MyException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public MyException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}
可以用throw new MyException(“自定义异常”);来抛出我们创建的自定义异常。
finally 关键字
与其他语言的模型相比,finally 关键字是对 Java 异常处理模型的最佳补充。finally 结构使代码总会执行,而不管有无异常发生。使用 finally 可以维护对象的内部状态,并可以清理非内存资源。
public class TestFinally {
public static void main(String[] args) {
System.out.println(test());//输出 1,c++是执行了但是函数值在这执行就已经返回了
try {
} finally {
// 这种语句块,目的就是想在finally中写,关键的代码
}
}
public static int test() {
int a = 10;
int b = 10;
int c = 0;
try {
c = a / b;
return c;
} catch (Exception e) {
System.out.println("出现了异常"+ e.getMessage());
return 0;
} finally {
// finally语句块,这个写代码必须要执行!!!
// 垃圾回收,资源释放等等
// 注意,如果在finally之前已经return,这儿即便是++,也不会影响结果!!!
c++;
System.out.println("这个的代码必须执行");
}
// System.out.println("代码向下继续执行了");
// return c;
}