异常指的是程序在执行过程中,出现的不能正常执行的情况,最终导致JVM(虚拟机)的非正常的停止的一种指令流。
例如:
public class ExceptionDemo{ public static void main(String argsp[]){ int i = 1 ; int j = 0 ; int temp = i / j ; // 进行除法运算` System.out.println("temp = " + temp) ; } }运行结果:
Excepti on in thread "main" java.lang.ArithmeticException: / by zero at ExceptionDemo.main(ExceptionDemo.java:5)出错的地方就是“int temp = i/j;”,该语句出现异常,导致程序无法正常运行,后面语句不在执行,退出程序。
为了程序的遇到此类异常仍能正常运行,外我们采用异常的处理机制try-catch。
异常处理的格式语法如下:
try{ // 有可能出现异常的语句块 }catch(异常类型1 对象名1){ //异常的操作 }catch(异常类型2 对象名2){ //异常的操作 } . . . finally{ // 异常处理统一出口 }使用异常处理就是给了程序一个补救错误的措施!
catch里面可以使用:
catch(ArithmeticException|InputMismatchException e) 指的是ArithmeticException或InputMismatchException异常发生时匹配到该catch进行处理 catch (RuntimeException e) 指的是RuntimeException类错误发生时匹配到该catch进行处理RuntimeException包含了许多的子类(包括ArithmeticException、InputMismatchException) catch(Exception e) 指的是所有的异常它都可以处理(不建议这样写)此关键字主要再方法的声明上使用,表示方法不处理异常,而交给调用者处理,它的格式:
返回值 方法名称()throws Exception{ }多处理异常格式2: 了解一下就可以 catch(ArithmeticException|InputMismatchException e)类
import java.util.InputMismatchException; import java.util.Scanner; /* * 多处理异常格式2: 了解一下就可以 * */ public class Demo3 { public static void main(String[] args) { haha(); System.out.println("程序执行完毕,正常结束"); } private static void haha() { try { Scanner input = new Scanner(System.in); System.out.println("请输入一个数字:"); int x = input.nextInt(); System.out.println("请输入一个数字:"); int y = input.nextInt(); System.out.println(x / y); System.out.println("处理完闭"); } catch (ArithmeticException|InputMismatchException e) { // 出现该错误ArithmeticException或InputMismatchException时进入catch System.out.println("请输入非0"); } } }多处理异常格式3: 常用的格式 catch (RuntimeException e)
import java.util.InputMismatchException; import java.util.Scanner; /* * 多处理异常格式3: 常用的格式 * */ public class Demo4 { public static void main(String[] args) { haha(); System.out.println("程序执行完毕,正常结束"); } private static void haha() { try { Scanner input = new Scanner(System.in); System.out.println("请输入一个数字:"); int x = input.nextInt(); System.out.println("请输入一个数字:"); int y = input.nextInt(); System.out.println(x / y); System.out.println("处理完闭"); } catch (RuntimeException e) { /* * 多态处理 * 1. ArithmeticException * 2. InputMismatchException * 都是RuntimeException异常(父类) */ System.out.println("输入有误!"); }finally { /* * 必然执行的异常统一处理出口 * 无论是否发生异常,finally必然执行 * 还可:IO处理,网页处理 * 面试:finally在某某情况下是不会执行(如果不是特殊情况它会执行) * 1. 程序关闭(软件在电脑利没了) * 2. 电脑停电 */ } } }我们先看下面两端代码
public class Demo5 { public static void main(String[] args) { int a = haha(); System.out.println(a); } /* * 此时得到的结果是a=10 * 分析: * 1. try当中的return备份到的是a的数值(栈当中直接备份数值) * 2. 当改变a的数值的时候备份的数值不会变化 * 3. 与Demo6形成对比 * */ public static int haha(){ int a = 10; try{ return a; }catch (Exception e){ //直接退出JVM后,finally是不会执行的 //System.exit(status:0);//该代码直接会导致程序退出JVM虚拟机 return a; }finally { //次方法执行时必须执行 a = 20; } } }上面程序得到的结果是10,
public class Demo6 { public static void main(String[] args) { Preson p = haha(); System.out.println(p.age); } /* * 此时得到的结果是a=20 * 分析: * 1. try当中return的时候备份的是p的地址(栈得到是堆的地址) * 2. 最后finally通过地址改变了地址上的数值,最后输出的p.age就是最后的赋值 * 3. 地址与数值备份的问题探讨 * */ public static Preson haha(){ //返回Preson类型的数据 Preson p = new Preson(); try{ p.age = 11; return p; }catch (Exception e){ return null; }finally { //次方法执行时必须执行 p.age = 20; } } public static class Preson{ int age; } }而这一段程序得到的结果是20。
那么为什么两端代码try-catch过后得到的结果与我们一开始所理解的点不一样呢?当此时得到的结果是a=10
try当中的return备份到的是a的数值(栈当中直接备份数值)当改变a的数值的时候备份的数值不会变化与Demo6形成对比当结果为a=20
try当中return的时候备份的是p的地址(栈得到是堆的地址)最后finally通过地址改变了地址上的数值,最后输出的p.age就是最后的赋值地址与数值备份的问题探讨