Java面向对象之异常【一】

Java面向对象之异常【二】

往期回顾:上一篇我们大致总结了异常的继承体系,说明了Exception和Error两个大类都继承于顶级父类Throwable,又谈到编译时异常与运行时异常的区别,谈到异常的处理方式,以及处理方式中关于捕获方式的几种类型。

本篇承上启下,将从异常的其余部分进行总结,但是毕竟现在处于初学阶段,未必能够体会异常在真实场景中运用的便利之处,所以本文只是对目前所学内容的归纳整理,后续新的体会将会及时更新。

捕获异常的规则

  • 在执行try块的过程中没有出现异常,那么很明显,没有异常当然就会跳过catch子句
  • 相反,如果抛出了一个异常,那么就会跳过try中的剩余语句,开始查找处理该异常的代码。以下是查找处理异常代码的具体过程:
  • 从当前方法开始,沿着方法的调用链,按照异常的反向传播方向找到异常的处理代码。
  • 从第一个到最后一个检查catch块,判断是否相匹配。如果是,那么恭喜!直接进入catch块中执行处理异常语句;如果不是,就将该异常传给方法的调用者,在调用者中继续执行相同步骤:匹配就处理,不匹配就向上传……
  • 直到最后如果都没有找到的话,程序将会终止,并在打印台上打印出错信息。

    如果是相对单一方法而言,其实是很简单的;如果方法层层嵌套呢,情况又是咋样的呢,咱们来验证一下以上内容:
//主方法
public static void main(String[] args) {
try{
//调用m1()
m1();
System.out.println("ExceptionMyDemo.main");
}catch (Exception e){
System.out.println("ExceptionMyDemo.main.catch");
}
}
//m1()
private static void m1(){
try{
//调用m2()
m2();
System.out.println("ExceptionMyDemo.m1");
}catch (NullPointerException e){
System.out.println("ExceptionMyDemo.m1.catch");
}
}
//m2()
private static void m2(){
String str = null;
System.out.println(str.hashCode());
}
//测试结果:
ExceptionMyDemo.m1.catch
ExceptionMyDemo.main
  • 可以看到,m1中捕获了m2抛出匹配的空指针异常类型,直接处理,在main方法中就接收不到异常,也就正常执行。
  • 假如我们把m1的catch的异常类型换成其他的类型,比如catch (ArithmeticException e),这时的测试结果会是这个样子:
//更改之后的测试结果:
ExceptionMyDemo.main.catch

因为m2()抛出的异常在m1中并没有被合适地处理,所以向上抛出,在main方法中找到了处理方法,遂执行处理语句。

  • 依据我们上面所说,如果在上面更改之后的基础上,再把main方法中的处理异常语句删去,那么程序运行的结果会是啥呢?哦,不出所料,是下面的结果:

因为抛出的异常没人处理,它就会在控制台上打印异常的栈轨迹,关于抛出的异常信息,我们接下来进行详细分析。

访问异常信息

我们提到,无论是虚拟机抛出异常还是我们主动抛出,异常的错误信息都包含其中,以便于我们得知并更好地处理异常,那么顺着上面所说,我们刚刚看到的就是异常的栈轨迹:

  • public void printStackTrace():默认将该Throwable对象及其调用栈的跟踪信息打印到标准错误流。
  • public String getMessage():返回描述异常对象信息的字符串。
  • public String toString():异常信息message为空就返回异常类的全名,否则返回全名:message的形式。
  • public StackTraceElement[] getStackTrace():返回栈跟踪元素的数组,表示和该异常对象相关的栈的跟踪信息。

异常对方法重写的影响

  • 异常对方法重载没有影响。
  • 方法重写时,子类中重写的方法抛出的编译时异常不能超过父类方法抛出编译时异常的范围

finally详解

名言警句:无论异常是否会发生,finally修饰的子句总是会被执行

于是我们进行了简单的尝试:

public static void m2(){
try{
System.out.println("0");
System.out.println(1/0);
System.out.println("1");
}
catch (Exception e){
System.out.println("2");
}
finally {
System.out.println("3");
}
System.out.println("4");
}
//测试结果
0 2 3 4 被打印在控制台上
  • 可以看到1没有被打印,因为在执行 System.out.println(1/0);时发生了异常,于是进入catch块,finally子句必会被执行,然后执行try语句后的下一条语句。

  • 想象以下:假如把接收异常的实例类型改为另外一个不匹配的类型的话,也就是说无法正常捕获,结果又会如何呢?结果如下:

  • 很明显,这时候finally的效果就出来了,就算你出了异常,我finally块中的语句必须要执行,这个在现实场景中对于释放资源起了很关键的作用,但是具体来说,由于还没有学习后面的内容,就暂且不提了,有些东西还是体会之后会更加真实一些。

  • 还有一个注意点就是4也没有被打印出来,是因为没有捕获到异常,将会把异常抛给调用者,所以不会执行System.out.println("4");

但是,化名为几千万个为什么的我又开始疑惑了,我们直到return可以将方法直接返回,强制退出。那么如果在try中使用return语句,finally还会不会不忘初心,继续执行呢?

前方高能!各单位注意!!!

猜猜看,这四个方法执行结果是啥呢?

private  static int m1(){
try{
return 1;
}catch(Exception e){
}
return 2;
}
private static int m2(){
try{
return 1;
}finally {
return 2;
}
//使用finally子句时可以省略catch块
}
private static int m3(){
try{
return 1;
}finally {
try{
return 2;
}finally {
return 3;
}
}
}
private static int m4(){
int i = 4;
try{
return i++;
}finally {
i++;
}
}

答案揭晓:分别是:1,2,3,4。你们猜对了吗?哈哈……

我想前三个答案应该是毋庸置疑的,但是这第四个就有点离谱了。不是说finally语句一定会执行吗,执行哪去了呢,你要是执行的话,你i难道不应该变成6了吗?

额……咳咳,这个嘛,我也有点迷惑,但是经过一番讨教,稍微懂了一些:

  • 当执行try之前,如果后面有finally,会将try中的返回过程延迟,就是说把i=4放到结果区。
  • 然后在计算区进行自增运算变为5,finally语句一定会执行,但是只是在计算区域自增为6了,结果区域还是原来的那个4。
  • 不信的话,你可以在finally语句的i++后面看看i的值,它!就是6!所以说finally子句一定执行是毋庸置疑的的!

但是如果进行改变的是引用数据类型的变量时,那么就会随之改变了,人家村的是地址,改的就是本身。我在这边就稍微来个简单的例子奥:

public static Student m(){
Student s = new Student();
try{
s.age = 20;
s.name = "天乔";
return s;
}finally { s.name = "巴夏";
s.age = 2;
}
}
//测试结果
//Student{age=2, name='巴夏'}

本文若有叙述不当之处,还望评论区批评指正哦!

Java面向对象之异常详解的更多相关文章

  1. java基础(十五)----- Java 最全异常详解 ——Java高级开发必须懂的

    本文将详解java中的异常和异常处理机制 异常简介 什么是异常? 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常. Java异常的分类和类结构图 1.Java中的所 ...

  2. Java中的异常详解

    一.异常定义 阻止当前方法或作用域继续执行的问题,称为异常 二.异常分析      所有不正常类都继承Throwable类,这个类主要有两个子类Error类和Exception类.Error指系统错误 ...

  3. JAVA面向对象-----main方法详解

    JVM看不懂的可以跳过,这里不做过多解释,(^__^) 嘻嘻-- 主函数是静态的 public static void main(String[] args){ } 主函数是什么:主函数是一个特殊的函 ...

  4. Java面向对象12——static详解

    static  package oop.demon01.demon07; ​ // static : public class Student { ​     private static int a ...

  5. Java面向对象之异常【一】

    目录 Java面向对象之异常[一] 异常的继承体系 Error Exception 异常是否受检 unchecked exceptions(不受检异常) checked exceptions(受检异常 ...

  6. java反射机制深入详解

    java反射机制深入详解  转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...

  7. java web.xml配置详解(转)

    源出处:java web.xml配置详解 1.常规配置:每一个站的WEB-INF下都有一个web.xml的设定文件,它提供了我们站台的配置设定. web.xml定义: .站台的名称和说明 .针对环境参 ...

  8. Java编程配置思路详解

    Java编程配置思路详解 SpringBoot虽然提供了很多优秀的starter帮助我们快速开发,可实际生产环境的特殊性,我们依然需要对默认整合配置做自定义操作,提高程序的可控性,虽然你配的不一定比官 ...

  9. java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock

    原文:java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock 锁 锁是用来控制多个线程访问共享资源的方式,java中可以使用synch ...

随机推荐

  1. Java多线程遍历文件夹,广度遍历加多线程加深度遍历结合

    复习IO操作,突然想写一个小工具,统计一下电脑里面的Java代码量还有注释率,最开始随手写了一个递归算法,遍历文件夹,比较简单,而且代码层次清晰,相对易于理解,代码如下:(完整代码贴在最后面,前面是功 ...

  2. 2015-2016 ACM-ICPC Southwestern Europe Regional Contest (SWERC 15)

    C. Canvas Painting 合并果子. E. Wooden Signs \(dp(i,l,r)\)表示第\(i\)块木板的长度区间为\([l,r]\)的方案数,根据题意,\(l\)或\(r\ ...

  3. springboot 2.1.6.RELEASE pom 第一行报错

    eclipse创建springboot 2.1.6.RELEASE  pom第一行报错 在pom.xml 文件的properties中加入maven jar插件的版本号 <maven-jar-p ...

  4. Python--day25--复习(单继承和多继承的总结)

  5. Python--day40--threading模块

    import time from threading import Thread class MyThread(Thread): def __init__(self,arg): super().__i ...

  6. 【codeforces 764B】Timofey and cubes

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  7. win10 uwp release 因为 Entry Point Not Found 无法启动

    本文告诉大家如果在使用 release 编译时,无法启动应用,出现 Entry Point Not Found 如何让应用运行. 程序"[30760] xx.exe"已退出,返回值 ...

  8. 2018-3-31-C#-谁改了我的代码

    title author date CreateTime categories C# 谁改了我的代码 lindexi 2018-3-31 21:15:3 +0800 2018-2-13 17:23:3 ...

  9. 2018-11-8-WPF-获取下载内容长度

    title author date CreateTime categories WPF 获取下载内容长度 lindexi 2018-11-08 20:18:15 +0800 2018-11-08 20 ...

  10. Apache工具集

    commons-collections-3.2.jar 转自:http://www.open-open.com/lib/view/open1384437456993.html