Java 异常分类及处理
1.异常及代码不正常执行,异常类Throwable 创建一个异常对象并抛出 就是异常的产生。此时Java会中断
1.1 Errow类 一般为代码缺陷 不应该被异常处理
1.2 Exception 分为 编译异常 和 运行异常 (都需要修复)
1.3Throwable 中长用的方法
例1
public void printStackTrace() // 打印异常的详细信息 包含 ①异常类型 ②异常原因 ③异常出现的位置
public String getMessage() // 打印异常原因 (注意返回值是字符串)
public class ExceptionTest { public static void main(String[] args) { int[] arr = new int[]{1,2}; ArrayTool.print(arr, 2); } } class ArrayTool{ public static void print(int[] arr,int index) { System.out.println(arr[index]); //1 } }
执行过程
① 数组索引值2的值没有找到,运行发生异常,JVM识别异常为 java.lang.ArrayIndexOutOfBoundsException (数组越界)
这个异常本身存在 描述内容包括 异常名称 异常内容 异常的产生位置.Java将这些信息直接封装到异常对象里 new ArrayIndexOutOfBoundsException(2)
② throw new ArrayIndexOutOfBoundsException(2) 产生异常对象
③ JVM 将异常对象抛给调用者main()方法
④ main()方法接受到了数组索引越界异常对象。由于没有处理异常 main()方法直接抛给调用者JVM.当JVM收到异常后 将异常对象中的 名称 内容 位置 显示出来 同时让程序停止
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at com.baidu.www2.ArrayTool.print(ExceptionTest.java:11)
at com.baidu.www2.ExceptionTest.main(ExceptionTest.java:6)
2.异常的处理
2.1try
2.2catch
2.3finally
作者:一只Tom猫 链接:https://zhuanlan.zhihu.com/p/90223112 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 public class TryCatchDemo { public static void main(String[] args) { try {// 当产生异常时,必须有处理方式。要么捕获,要么声明。 read("b.txt"); } catch (FileNotFoundException e) {// 括号中需要定义什么呢? //try中抛出的是什么异常,在括号中就定义什么异常类型 System.out.println(e); } System.out.println("over"); } /* * * 我们 当前的这个方法中 有异常 有编译期异常 */ public static void read(String path) throws FileNotFoundException { if (!path.equals("a.txt")) {//如果不是 a.txt这个文件 // 我假设 如果不是 a.txt 认为 该文件不存在 是一个错误 也就是异常 throw throw new FileNotFoundException("文件不存在"); } } }
2.5 finally 代码块与return语句
还有个特别重要的点就是在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行,另外finally语句中也可以有return语句,但是尽量避免有return语句(会报警告)
2.4throw
抛出异常 throw new [异常类型("内容输出")]
throw new ArrayIndexOutOfBoundsException("索引越界");
public class ExceptionTest { public static void main(String[] args) { int[] arr = new int[]{1,2}; ArrayTool.print(arr, 2); } } class ArrayTool{ public static void print(int[] arr,int index) { if(index<0||index>=arr.length) { throw new ArrayIndexOutOfBoundsException("索引越界"); } System.out.println(arr[index]); } }
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 索引越界
at com.baidu.www2.ArrayTool.print(ExceptionTest.java:12)
at com.baidu.www2.ExceptionTest.main(ExceptionTest.java:6) (可以与例1对比)
2.5throws
异常产生 我们已经可以使用throw将异常抛出,也将问题返回给了方法的调用者。那么对于调用者来说,怎么处理?一种是进行捕获处理,另一种就是继续将问题声明出去m使用throws声明处理
关键字throws运用于方法声明之上,throws格式为修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ },用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常).
public class ExceptionTest { public static void main(String[] args) throws IOException { read("a.txt"); } // 如果定义功能时有问题发生需要报告给调用者。可以通过在方法上使用throws关键字进行声明 public static void read(String path) throws FileNotFoundException,IOException { if (!path.equals("a.txt")) {//如果不是 a.txt这个文件 // 我假设 如果不是 a.txt 认为 该文件不存在 是一个错误 也就是异常 throw throw new FileNotFoundException("文件不存在"); } if (!path.equals("b.txt")) { throw new IOException(); } } }
throw
- 表示方法内抛出某种异常对象
- 如果异常对象是
非 RuntimeException则需要在方法申明时加上该异常的抛出 即需要加上throws语句 或者 在方法体内try catch处理该异常,否则编译报错 - 执行到
throw语句则后面的语句块不再执行
throws
方法的定义上使用 throws 表示这个方法可能抛出某种异常 2、需要由方法的调用者进行异常处理
2.6 异常注意事项
多个异常使用捕获又该如何处理呢?
- 多个异常分别处理。
- 多个异常一次捕获,多次处理。
- 多个异常一次捕获一次处理。
一般我们是使用一次捕获多次处理方式,格式如下:
try{
编写可能会出现异常的代码
}catch(异常类型A e){ 当try中出现A类型异常,就用该catch来捕获.
处理异常的代码
//记录日志/打印异常信息/继续抛出异常
}catch(异常类型B e){ 当try中出现B类型异常,就用该catch来捕获.
处理异常的代码
//记录日志/打印异常信息/继续抛出异常
}
注意:这种异常处理方式,要求多个catch中的异常不能相同,并且若catch中的多个异常之间有子父类异常的关系,那么子类异常要求在上面的catch处理,父类异常在下面的catch处理。
异常注意小结:
- 运行时异常被抛出可以不处理。即不捕获也不声明抛出。
- 如果
finally有return语句,永远返回finally中的结果,避免该情况. 上面也提到过 - 如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常。
- 父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
自定义异常
// 自定义异常类 // 1.继承Exception类 // 2.创建版本号 static final long serialVersionUID = -3387516993124229948L; // 3.创造构造函数 public class EcDef extends Exception { static final long serialVersionUID = -3387516993124229948L; public EcDef() { super(); // TODO Auto-generated constructor stub } public EcDef(String message) { super(message); // TODO Auto-generated constructor stub } }
public class EcmDef { public static void main(String[] args) { try { int i = Integer.parseInt(args[0]); int j = Integer.parseInt(args[1]); int result = ecm(i, j); System.out.println(result); } catch (NumberFormatException e) { System.out.println("数据类型不一致"); e.printStackTrace(); System.out.println(e.getMessage()); } catch (ArrayIndexOutOfBoundsException e) { // e.printStackTrace(); System.out.println("缺少命令行参数"); }catch (ArithmeticException e) { System.out.println("除以0的异常"); // e.printStackTrace(); }catch (EcDef e) { System.out.println(e.getMessage()); } } public static int ecm(int i, int j) throws EcDef{ if (i < 0 || j < 0) { throw new EcDef("分母或分子为负数了!"); } return i / j; } }

原文链接 https://juejin.im/post/5dc0ba1c5188255f77580427

浙公网安备 33010602011771号