/* 异常 Java语言中,将程序执行中发生的不正常情况称为"异常"。(语法错误和逻辑错误不是异常) 执行过程中所发生的异常可分为两类 1.Error:Java虚拟机无法解决的严重问题,程序会崩溃 如:JVM系统内部错误、资源耗尽等严重情况 2.Exception:其他因编程或偶然的外在因素导致的一般问题,可以使用针对性代码进行处理 如:空指针访问、试图读取不存在的文件、网络连接中断等 Exception又分为两大类:运行异常(程序运行时发生的异常)和编译异常(编译器检查出的异常) 运行异常:编译器不要求强制处置的异常,一般指编程时的逻辑错误,是程序员应该避免出现的异常 对于运行异常可以不作处理,因为这类异常很普遍,若全处理会对程序可读性和运行效率产生影响 编译异常:是编译器要求必须处置的异常 异常体系 Throwable(异常根类) Error StackOverflowError(栈溢出) OutOfMemoryError(内存溢出) .... Exception RuntimeException(运行异常) NullPointerException(空指针异常) ArithmeticException(算数异常) ArrayIndexOutOfBoundsException(数组索引异常) ClassCastException(类型转换异常) NumberFormatException(数字格式异常) ..... 编译异常 SQLException(操作数据库时,查询表可能发生异常) FileNotFoundException(操作一个不存在的文件时发生异常) ClassNotFoundException(加载类而该类不存在时发生异常) EOFException(操作到文件末尾时发生异常) ..... */
/* 异常处理:当异常发生时,对异常进行处理的方式 1.try-catch-finally 程序员在代码中捕获发生的异常,自行处理 基本语法 try{ //可疑代码 }catch(异常){ //对异常进行处理 }finally{ } //当异常发生时,系统将异常封装成Exception对象e,传递给catch进行处理 //如果没有发生异常,catch代码块不执行 //finally也可省略不写 //无论是否有异常,finally代码块始终执行,因此通常将释放资源的代码放在finally //可以有多个catch语句,捕获不同的异常,要求父类异常在后,子类异常在前 // 如Exception在后,NullPointerException在后 // 如果发生异常,只会匹配一个catch //也可try-finally配合使用,相当于没有捕获异常,执行完finally后退出程序 2.throws 将发生的异常抛出,交给调用者处理,最顶级处理者是JVM(输出异常信息,退出程序) 在方法声明中用throws语句可以声明抛出异常列表,即抛出多个异常, throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类 1.对于运行异常,程序如果没有处理,默认使用throws的方式处理 2.子类重写父类方法时,所抛出的异常类型要与父类抛出的异常一致或为父类抛出异常的子类 3.在throws过程中,如果有try-catch,相当于处理异常,可不必用throws */ // 应用——如果用户输入的不是一个整数,提示反复输入,直到输出一个整数为止 public class Exception02 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (true){ System.out.println("请输入一个整数"); try{ int num = Integer.parseInt(scanner.next()); break; }catch (NumberFormatException e){ System.out.println("输入有误"); } } System.out.println("输入正确"); } }
/* 自定义异常 当程序中出现了某种”错误“,但该错误并没有在Throwable子类中描述,这时可以自己设计异常类,用于描述该信息 使用 定义类:自定义异常类名 继承Exception或RuntimeException(一般继承RuntimeException) 若继承Exception,属于编译异常 若继承RuntimeException,属于运行异常 */ // 接收对象年龄时,要求范围在18-60岁,否则抛出自定义异常 import java.util.Scanner; public class Exception03 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("输入年龄"); int age = scanner.nextInt(); if(!(age >= 18 && age <= 60)){ throw new AgeException("年龄需在18岁-60岁之间"); } System.out.println("输入正确"); } } class AgeException extends RuntimeException{ public AgeException(String message) {//构造器 super(message); } } /* throw与throws的区别 意义 位置 throws 异常处理的一种方式 方法声明处,后接异常类型 throw 手动生成异常的关键字 方法体中,后接异常对象 */
// 练1 public class ExceptionExe02 { public static int method(){ try{ String[] names = new String[3]; if(names[1].equals("jack")){ System.out.println(names[1]); }else { names[3] = "tom"; } return 1; }catch (ArrayIndexOutOfBoundsException e){ return 2; }catch (NullPointerException e){ return 3; }finally{ return 4; } } public static void main(String[] args) { System.out.println(method()); } } // 练2 public class ExceptionExe02{ public static int method(){ int i = 1; try{ i++;//i=2 String[] names = new String[3]; if(names[1].equals("jack")){ System.out.println(names[1]); }else { names[3] = "tom"; } return 1; }catch (ArrayIndexOutOfBoundsException e){ return 2; }catch (NullPointerException e){//捕获 return ++i;//i=3 }finally{//必须执行 return ++i;//i=4 } } public static void main(String[] args) { System.out.println(method()); } } // 练3 public class ExceptionExe02 { public static int method(){ int i = 1; try{ i++;//i=2 String[] names = new String[3]; if(names[1].equals("jack")){ System.out.println(names[1]); }else { names[3] = "tom"; } return 1; }catch (ArrayIndexOutOfBoundsException e){ return 2; }catch (NullPointerException e){//捕获 return ++i;//i=3 =>因为return不会马上执行,保存临时变量temp = 3;最终返回3 }finally{//必须执行 ++i;//i=4 System.out.println("i=" + i);//i=4 } } public static void main(String[] args) { System.out.println(method()); } }
/* 编写一个程序,接收两个整数,计算两数相除,要求使用方法cal(int n1,int n2) 对数据格式不正确、缺少命令行参数、除0进行异常处理 */ public class ExceptionExe { public static void main(String[] args) { try { int n1 = Integer.parseInt(args[0]); int n2 = Integer.parseInt(args[1]); double res = cal(n1,n2); System.out.println("计算结果=" + res); }catch (ArrayIndexOutOfBoundsException e){ System.out.println("参数个数不对"); }catch (NumberFormatException e){ System.out.println("参数格式不正确"); }catch (ArithmeticException e){ System.out.println("除0异常"); } } public static double cal(int n1,int n2){ return n1 / n2; } }