为什么要学习异常?
如果不处理异常,就会交给JVM处理异常,一旦交给JVM,程序就会异常终止。
java中异常体系:错误和异常
错误是代码中客观存在的,有两种方式处理:
LBYL
: Look Before You Leap.
在操作之前就做充分的检查
.
EAFP
: It's Easier to Ask Forgiveness than Permission. "
事后获取原谅比事前获取许可更容易
".
也就是先操作
,
遇到
问题再处理
.
异常分为运行时异常(非受查异常)和编译时异常(受查异常)
每个人开始写代码都会遇到或多或少的异常,例如:
public static void main(String[] args) {
System.out.println(10/0); //算术异常
}
public static void main(String[] args) {
int[] arr = {1, 2, 3};
System.out.println(arr[100]); //数组越界异常
}
public int num = 10;
public static void main(String[] args) {
TestDemo t = null;
System.out.println(t.num); //空值异常
}
所以:异常就是在程序运行时出现错误时通知调用者的一种机制。
处理方式:
一、捕获异常 try... catch.......
public static void main(String[] args) {
try {
System.out.println(10/0);
}catch (ArithmeticException e) {
System.out.println("算术异常");
}
System.out.println("我还能行");
}
所以只要捕获相应的异常,程序就能继续运行
也可以捕获多个异常:
public static void main(String[] args) {
try {
System.out.println(10/5);
int[] array = null;
System.out.println(array.length);
}catch (ArithmeticException | NullPointerException e) {
//可以用(Exception e)直接捕获全部异常,不推荐
e.printStackTrace();
System.out.println("异常");
}
System.out.println("我还能行");
}
但是,catch只能处理对应种类的异常。
finally:finally块当中的代码一定会被执行
public static void main(String[] args) {
try {
System.out.println(10 / 0);
int[] array = null;
System.out.println(array.length);
}catch (Exception e) {
e.printStackTrace();
System.out.println("异常");
}finally {
System.out.println("finally块当中的代码一定会被执行!");
}
System.out.println("我还能行");
}
public static void main(String[] args) {
System.out.println(func2());
}
public static int func2() {
try {
return 10;
} finally {
return 20;
}
}
//最后会打印出20
close:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
int a = scanner.nextInt();
System.out.println(10 / a);
int[] array = null;
System.out.println(array.length);
} catch (ArithmeticException | NullPointerException e) {
e.printStackTrace();
System.out.println("异常");
} finally {
System.out.println("finally块当中的代码一定会被执行!");
scanner.close(); //退出
}
System.out.println("我还能行");
}
当方法中的异常比较多,可以用throw声明异常:
public static void main(String[] args) {
try {
func();
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
System.out.println("after try catch");
}
public static void func() throws ArithmeticException,NullPointerException,ArrayIndexOutOfBoundsException {
int[] arr = {1, 2, 3};
System.out.println(arr[100]); //数组越界异常
}
下来是如何去写有异常的代码:有注释
public static double func(int x,int y)throws ArithmeticException{
if (y == 0) {
throw new ArithmeticException("除数为0"); //如果y = 0,抛出算术异常
}
return x*1.0 / y ;
}
//上面这个方法声明了会出现算术异常,但没有处理,下来我们写代码时就可以处理一下
public static void main5(String[] args) {
try{
System.out.println(func(10,0));
}catch (ArithmeticException e){
e.printStackTrace();
System.out.println("除数为零");
}
}
自定义异常:有注释
class MyException extends Exception{ //继承于编译时异常更安全
public MyException() {
}
public MyException(String message) {
super(message);
}
}
public class TestDemo {
public static void func3(int x)throws MyException{
if (x == 10) {
throw new MyException("x==10"); //如果x=10,抛出异常
}
}
public static void main(String[] args) {
try {
func3(10); //调用方法时可以自己处理异常
}catch (MyException e) {
e.printStackTrace();
}
}
}