认识Java中的异常
LBYL 和 EAFP
-
LBYL (look before you leap) 在操作的时候就做充分的检查
-
EAFP (Easier to Ask Forgiveness than Permission)先操作遇到问题再处理
-
就比如你想吃你妹妹的零食,你先问你妹妹可以吃嘛,你妹妹同意后再去吃,就是LBYL。
-
而你先吃了,在告诉你妹妹,你妹妹哭了,你带你妹妹去买新的零食,就是EAFP。
// 1.LBYL int x = 0; if (x == 0) { // 处理异常 return; } int y = 10/x; // 2.EAFP try { int x = 0; int y = 10/x }catch (Exception e) { // 处理异常 }
-
认识异常
- 异常就是在程序在 运行时出现的错误时通知调用者的一种机制
- 可以将其分为编译时异常和运行时异常
- 异常的核心思想就是EAFP。先去运行程序,遇到问题后再去处理。
异常的分类
- Throwable 时异常的顶级父类,派生出两个父类,Error和Exception
- Error指的是Java运行时内部资源错误和资源耗尽错误,应用程序不抛出此类异常,这种内部错误一旦出现,程序会终止并且告知用户,没有其他办法
- 编译时异常 一旦出现我们用的idea编译软件就会提醒我们需要去处理异常 比如我们IO异常和处理数据库时的有些异常。
- RuntimeException 为运行时异常,我们常见的有空指针异常,栈溢出以及数组越界异常等
处理异常的方法
-
一种就是抛出异常 throw
-
一种就是try catch包裹异常
其实在我们实际处理的时候我们一般都是两种方式相互结合着去处理我们方法中可能出现的异常。
两种方法的比较
// 当我们不去处理异常的时候 执行下面代码 public static void main(String[] args) { int u = 10/0; System.out.println(123); } // 结果为 Exception in thread "main" java.lang.ArithmeticException: / by zero at D.main(D.java:4) Process finished with exit code 1 // 不会打印123 // 当我们处理异常 使用抛出的方式的时候 public static void main(String[] args) throws Exception{ int u = 10/0; System.out.println(123); } // 结果为 Exception in thread "main" java.lang.ArithmeticException: / by zero at D.main(D.java:4) Process finished with exit code 1 // 处理异常使用 try catch的方法 自己处理异常 public static void main(String[] args) { try { int u = 10/0; } catch (Exception e) { e.printStackTrace(); } System.out.println(123); } // 结果为 注意 打印出了123 java.lang.ArithmeticException: / by zero at D.main(D.java:5) 123 Process finished with exit code 0 // 如果我们不想让他在打印面板上打印出来 public static void main(String[] args) { try { int u = 10/0; } catch (Exception e) { } System.out.println(123); } //结果是 123 Process finished with exit code 0
我们处理异常的时候一般是抛出异常和自己处理异常的方法相结合
// 1. 第一种抛出java中的异常类,就不会打印123了 public static void main(String[] args){ try { int u = 10/0; } catch (Exception e) { throw new RuntimeException(); } System.out.println(123); } // 打印结果为 Exception in thread "main" java.lang.RuntimeException at D.main(D.java:7) Process finished with exit code 1 // 2. 我们也可以自定义异常,来处理这个异常 注意构造方法 //自定义异常类 public class MyException extends Exception{ public MyException(String message, Throwable cause) { super(message, cause); } } // 抛出自定义异常类的时候需要在main方法上抛出这个自定义异常 public static void main(String[] args) throws MyException { try { int u = 10/0; } catch (Exception e) { throw new MyException("分母为0", e); } System.out.println(123); } // 打印结果为 Exception in thread "main" MyException: 分母为0 at D.main(D.java:7) Caused by: java.lang.ArithmeticException: / by zero at D.main(D.java:5) Process finished with exit code 1
线程中出现异常的话
- 线程中出现异常 如果run方法没有捕获到异常 线程就会结束 不会接下来执行
- 线程中无法使用在main方法上加上throws + 异常的方法来抛出异常,只能使用try catch的方法来处理异常
// 1. public static void main(String[] args) { Thread thread = new Thread(new Runnable() { @Override public void run() { try { for (int i = 8 ; i > -2; i--) { int y = 10/i; System.out.print(y + " "); } } catch (Exception e) { } } }); thread.start(); } //结果为 1 1 1 2 2 3 5 10 Process finished with exit code 0 //2. public static void main(String[] args) { Thread thread = new Thread(new Runnable() { @Override public void run() { try { for (int i = 8 ; i > -2; i--) { int y = 10/i; System.out.print(y + " "); } } catch (Exception e) { e.printStackTrace(); } } }); thread.start(); } // 结果为 1 1 1 2 2 3 5 10 java.lang.ArithmeticException: / by zero at D$1.run(D.java:9) at java.lang.Thread.run(Thread.java:748) Process finished with exit code 0 // 3. public static void main(String[] args) { Thread thread = new Thread(new Runnable() { @Override public void run() { try { for (int i = 8 ; i > -2; i--) { int y = 10/i; System.out.print(y + " "); } } catch (Exception e) { try { throw new MyException("分母为0", e); } catch (MyException myException) { myException.printStackTrace(); } } } }); thread.start(); } // 打印结果为 1 1 1 2 2 3 5 10 MyException: 分母为0 at D$1.run(D.java:14) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.ArithmeticException: / by zero at D$1.run(D.java:9) ... 1 more