程序在运行过程中出现的不正常现象,出现异常不处理将终止程序运行。
异常处理的必要性:任何程序都可能存在大量的未知问题、错误;如果不对这些问题进行正常处理,则会导致程序的中断,造成损失
异常处理:Java编程语言使用异常处理机制为程序提供了异常处理的能力。
Throwable:可抛出的,一切错误或者异常的父类,位于Java.lang包中。
error:JVM、硬件、执行逻辑错误,不能手动处理
stackOverflowError:栈空间溢出
OutOfMemoryErro:内存不足
Exception:程序在运行和配置中产生的问题,可以处理
RuntimeException:运行时异常,可以处理,也可以不处理
CheckedException:检查时异常,必须处理
类型 | 说明 |
---|---|
NullPointerException | 空指针异常 |
ArragIndexOutOfBoundsExcption | 数组越界异常 |
ClassCastException | 类型转换异常 |
NumberFormatException | 数字格式化异常 |
ArithmeticException | 算术异常 |
//常见异常 //NullPointException 空指针异常 String s = null ; String s1 = "java"; System.out.println(s.equals(s1));
//ArragIndexOutOfBoundsExcption 数组越界异常 int[] i = new int[3]; System.out.println(i[4]);
//NumberFormatException 数字格式化异常 String s = "100a"; Integer i = Integer.valueOf(s); System.out.println(i);
//ClassCastException 类型转换异常 Object str = "hello"; Integer i = (Integer)str;
//ArithmeticException 算术异常 int i = 10/0; System.out.println(i);
当程序在运行时遇到不符合规范的代码或者结果时,会产生异常或者程序员使用throw关键字手动抛出异常。
按照方法的调用链反向传递,如果始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)
出现异常没有处理,程序在产生异常的地方中断
java的异常处理是通过5个关键字来实现
---try :执行可能产生异常的代码
---catch: 捕获异常并且处理
--- finally: 无论是否发生异常,代码都会执行
---throw:手动抛出异常
---throws: 声明方法可能要抛出的异常,由调用该方法的方法来处理,传递到main方法中时,如果没有处理,则由JVM进行默认异常处理(打印堆栈跟踪信息)。
手动退出JVM:System.exit(0);程序结束,后面的代码完全不执行
三种情况
1.没有出现异常,catch不执行
2.出现异常,catch捕获异常
3.出现异常,catch不能捕获(异常类型不匹配)
throws关键字:声明异常
使用原则:底层代码向上声明或者抛出异常,最上层一定要处理异常,否则程序中断
优先使用try {} catch{}处理异常
public static void main(String[] args) throws Exception{ //第一种处理异常 try { //第二种处理异常 divide(); } catch (Exception e) { System.out.println("存在异常"); } } public static void divide() throws Exception { Scanner input = new Scanner(System.in); System.out.println("请输入第一个数字"); int num1 = input.nextInt(); System.out.println("请输入第二个数字"); int num2 = input.nextInt(); int result = num1/num2; System.out.println("结果:"+ result); }
throw关键字:抛出异常
语法:throw 异常对象
public void setSex(String sex) { if(sex.equals("男")||sex.equals("女")) { this.sex = sex; }else { try { throw new Exception(); } catch (Exception e) { System.out.println("输入性别不符合要求");; } } } public void setAge(int age) throws Exception { if(age<200&&age>0){ this.age = age; }else { throw new Exception("年龄不符合要求"); //声明异常之后一定要进行处理,可以在方法上直接向上抛出或者直接trycatch,也可以在调用该方法的地方进行抛出或者trycatch } }
public static void main(String[] args) { Person p = new Person(); try { p.setAge(201); } catch (Exception e) { System.out.println(e.getMessage()); //年龄不符合要求 } p.setSex("神"); //输入性别不符合要求 System.out.println(p.toString()); //Person{sex='null', age=0, name='null'} } }
需要继承Exception或者Exception的子类,常用RuntimeException
必须提供构造方法
无参构造方法
String message参数的构造方法
public void setAge(int age) throws Exception { if(age<200&&age>0){ this.age = age; }else { throw new AgeExcption("年龄不符合要求"); //声明异常之后一定要进行处理,可以在方法上直接向上抛出或者直接trycatch, // 也可以在调用该方法的地方进行抛出或者trycatch } }
public class AgeExcption extends RuntimeException{ public AgeExcption() { } public AgeExcption(String message) { super(message); } public AgeExcption(String message, Throwable cause) { super(message, cause); } public AgeExcption(Throwable cause) { super(cause); } public AgeExcption(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } }
Person p = new Person(); try { p.setAge(201); } catch (Exception e) { e.printStackTrace(); //com.qf.ZiXi0606.AgeExcption: 年龄不符合要求 }
带有异常声明的方法重写(覆盖)
方法名、参数列表、返回值类型必须和父类相同
子类的访问修饰符和父类相同或者比父类更加宽泛。
子类中的方法,不能抛出比父类更多、更宽的检查时异常
异常的概念:程序在运行时出现的特殊情况
异常的分类:
RuntimeException:运行时异常,可处理,也可以不处理
CheckedException(Exception及其子类):检查时异常,必须处理
异常的产生:程序遇到错误,或者手动抛出(throw)异常
异常的传递:按照方法的调用链反向传递,如果始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)
异常的处理:try{ } catch { } finally { }
带有异常声明的方法覆盖:子类中的方法,不能抛出比父类更多、更宽的异常。、
在try中,当出现异常时,catch捕捉异常,try里面的代码块不会执行,但是try以外的代码可以执行。
在方法中,没有try catch 时,出现异常之后,进行抛出,异常之后的代码不会执行
在类中,一个方法调用另一个方法,被调用的方法出现异常,但是被catch捕获,则前者方法继续执行
try{}、catch()、finally{}中可以写return语句,但是尽量不要在finally中写return,会造成返回结果不正确。
如果try{}中有一个return,finally中的代码会执行。先执行finally中的代码,然后再返回结果,如果finally里面有return语句,会执行finally里面的return语句,返回结果,提前结束。
public static void add(){ int num = 10; System.out.println(num); //10 System.out.println(num++); //10 System.out.println(num); //11 System.out.println(++num); //12 }