Java进阶异常
Posted Ricky_0528
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java进阶异常相关的知识,希望对你有一定的参考价值。
文章目录
1 异常简介
错误在编写程序的过程中经常发生,包括编译期间和运行期间的错误
在程序运行过程中,意外发生的情况,背离程序本身的意图的表现,都可以理解为异常
2 异常处理简介
Throwable
- Error
- VirtualMachineError:虚拟机错误
- OutOfMemoryError:内存溢出
- ThreadDeath:线程死锁
- Exception
- Unchecked Exception:非检查异常
- RuntimeException
- NullPointerException:空指针异常
- ArrayIndexOutOfBoundsException:数组下标越界异常
- ArithmeticException:算术异常
- ClassCastException:类型转换异常
- RuntimeException
- Checked Exception:检查异常
- IOException:IO异常
- SQLException:SQL异常
- Unchecked Exception:非检查异常
异常处理机制为
-
抛出异常
- 异常类型
- 异常出现时的程序状态
-
捕捉异常
对于运行时异常、错误或可查异常,Java技术所要求的异常处理方式有所不同
- 对于可查异常必须捕捉、或者声明抛出
- 允许忽略不可查的RuntimeException(含子类)和Error(含子类)
- 捕获异常
- try:执行可能产生异常的代码
- catch:捕获异常
- finally:无论是否发生异常,代码总能执行
- 声明异常
- throws:声明可能要抛出的异常
- 抛出异常
- throw:手动抛出异常
3 使用try-catch-finally处理异常
public void method()
try
// 代码段1
// 产生异常的代码段2
catch(异常类型 ex)
// 对异常进行处理的代码段3
finally
// 代码段4
try块:用于捕获异常
catch块:用于处理try捕获到的异常
finally块:无论是否发生异常代码总能执行
语法要求:try块后可接零或多个catch块,如果没有catch块,则必须跟一个finally块,即try必须跟catch或finally组合使用
-
try-catch结构
package com.ricky.test; import java.util.Scanner; public class TryDemoOne public static void main(String[] args) try Scanner input = new Scanner(System.in); System.out.print("请输入第一个数:"); int one = input.nextInt(); System.out.print("请输入第二个数:"); int two = input.nextInt(); System.out.println("两个数的商为:" + (one / two)); catch(Exception e) e.printStackTrace(); // 将抛出的错误直接输出 finally System.out.println("运算结束");
-
多重catch结构
package com.ricky.test; import java.util.InputMismatchException; import java.util.Scanner; public class TryDemoOne public static void main(String[] args) try Scanner input = new Scanner(System.in); System.out.print("请输入第一个数:"); int one = input.nextInt(); System.out.print("请输入第二个数:"); int two = input.nextInt(); System.out.println("两个数的商为:" + (one / two)); catch(ArithmeticException e) System.out.println("除数不允许为0"); catch(InputMismatchException e) System.out.println("请输入整数"); catch(Exception e) // 通常建议在最后加上父类Exception用来追踪前面无法捕获的异常信息 // 一定是放在最后的 e.printStackTrace(); finally System.out.println("运算结束");
-
终止finally执行
package com.ricky.test; import java.util.InputMismatchException; import java.util.Scanner; public class TryDemoOne public static void main(String[] args) try Scanner input = new Scanner(System.in); System.out.print("请输入第一个数:"); int one = input.nextInt(); System.out.print("请输入第二个数:"); int two = input.nextInt(); System.out.println("两个数的商为:" + (one / two)); catch(ArithmeticException e) System.exit(1); // 非0即表示程序异常终止,后面的语句都不会执行包括finally System.out.println("除数不允许为0"); catch(InputMismatchException e) System.out.println("请输入整数"); catch(Exception e) e.printStackTrace(); finally System.out.println("运算结束");
-
return关键字不要用早finally语句块中,这样无论如何返回的都是finally中的值,前面try、catch中的return都失效了
4 使用throw和throws实现异常处理
可以通过throws声明将要抛出何种类型的异常,通过throw将产生的异常抛出
①throws
throws语句用在方法定义是声明该方法要跑出的异常类型
public void method() throws Exception1, Exception2,...,ExceptionN
// 可能产生异常的代码
当方法抛出异常列表中的异常时,方法将不对这些类型及其子类类型的异常作处理,而抛向调用该方法的方法,由他去处理
-
throws后面接多个异常类型,中间以逗号分隔
package com.ricky.test; import java.util.InputMismatchException; import java.util.Scanner; public class TryDemoOne public static void main(String[] args) try int result = test(); System.out.println("两个数的商为:" + result); catch(ArithmeticException e) System.out.println("除数不可以为0"); e.printStackTrace(); catch(InputMismatchException e) System.out.println("请输入整数"); e.printStackTrace(); public static int test() throws ArithmeticException, InputMismatchException Scanner input = new Scanner(System.in); System.out.print("请输入第一个数:"); int one = input.nextInt(); System.out.print("请输入第二个数:"); int two = input.nextInt(); return one / two;
-
throws后面接Exception
package com.ricky.test; import java.util.InputMismatchException; import java.util.Scanner; public class TryDemoOne public static void main(String[] args) try int result = test(); System.out.println("两个数的商为:" + result); catch (ArithmeticException e) System.out.println("除数不可以为0"); catch(InputMismatchException e) System.out.println("请输入整数"); catch(Exception e) e.printStackTrace(); public static int test() Scanner input = new Scanner(System.in); System.out.print("请输入第一个数:"); int one = input.nextInt(); System.out.print("请输入第二个数:"); int two = input.nextInt(); return one / two;
- throws Exception的情况,catch必须对Exception进行处理,前面Exception的子类都可以没有,因为Exception涵盖的范围很大
- 并且由于Exception包含了Checked Exception(检查异常),因此不对Exception进行处理,编译器会直接报错
-
书写文档注释,会提醒需要处理的异常(/** + 回车)
②throw
throw用来抛出一个异常,例如:throw new IOException();
throw抛出的只能够是可抛出类Throwable或者其子类的实例对象,例如throw new String("出错啦");
是错误的
-
方法一:通过try…catch包含throw语句——自己抛自己处理
public void method() try // 代码段1 throw new 异常类型(); catch(异常类型 ex) // 对异常进行处理的代码段2
-
方法二:通过throws在方法声明处抛出异常类型——谁调用谁处理,调用者可以自己处理,也可以继续向上抛
public void method() throws 异常类型 // 代码段1 throw new 异常类型();
此时可以抛出与throw对象相同的类型或者其父类,不可以为子类
同时建议抛出一个检查异常,因为这样编译器对于异常的约束更强
5 自定义异常
使用Java内置的异常类可以描述在编程时出现的大部分异常情况
也可以通过自定义异常描述特定业务产生的异常类型
所谓自定义异常,就是定义一个类,去继承Throwable类或者它的子类
CustomTryDemo.java
package com.ricky.test;
import java.util.Scanner;
public class CustomTryDemo
public static void main(String[] args)
try
testAge();
catch(HotelAgeException e)
System.out.println(e.getMessage());
System.out.println("不允许办理入住");
public static void testAge() throws HotelAgeException
System.out.print("请输入年龄:");
int age = new Scanner(System.in).nextInt();
if (age < 18 || age > 80)
throw new HotelAgeException();
else
System.out.println("欢迎入住!");
HotelAgeException.java
package com.ricky.test;
public class HotelAgeException extends Exception
public HotelAgeException()
super("18岁以下80岁以上入住酒店需要有人陪同");
6 异常链
在捕获一个异常之后,再抛出一个异常,新抛出的异常会导致之前的异常丢失,如:
package com.ricky.test;
public class ExceptionChain
public static void main(String[] args)
try
testThree();
catch(Exception e)
e.printStackTrace();
public static void testOne() throws HotelAgeException
throw new HotelAgeException();
public static void testTwo()
try
testOne();
catch (HotelAgeException e)
throw new Exception("新产生的异常1");
public static void testThree()
try
testTwo();
catch (Exception e)
throw new Exception("新产生的异常2");
为解决这个问题,Throwable类提供了一个构造方法
同时也提供了一个方法
package com.ricky.test;
public class ExceptionChain
public static void main(String[] args)
try
testThree();
catch(Exception e)
e.printStackTrace();
public static void testOne() throws HotelAgeException
throw new HotelAgeException();
public static void testTwo()
try
testOne();
catch (HotelAgeException e)
throw new Exception("新产生的异常1", e); //
public static void testThree()
try
testTwo();
catch (Exception e)
Exception ee = new Exception("新产生的异常2");
ee.initCause(e); //
throw ee;
由此可见,异常链就是将异常发生的原因一个传一个串起来,即把底层的异常信息传给上层,这样逐层抛出
7 总结
try-catch-finally
- 处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
- 在多重catch块后面,可以加一个catch(Exception)来处理可能会遗漏的异常
- 对于不确定的代码,也可以加上try-catch,处理潜在的异常
- 尽量去处理异常,切忌只是简单的调用printStackTrace()去打印输出
- 具体如何处理异常,要根据不同的业务需求和异常类型去决定
- 尽量添加finally语句去释放占用的资源
以上是关于Java进阶异常的主要内容,如果未能解决你的问题,请参考以下文章