1、什么是异常,java提供异常处理机制有什么用?

  • 什么是异常:程序执行过程中的不正常情况。
  • 异常的作用:增强程序的 健壮性

eg.

public class ExceptionTest01 {public static void main(String[] args) {int a = 10;int b = 0;// 实际上JVM在执行到此处的时候,会new异常对象:new ArithmeticException("/ by zero");// 并且JVM将new的异常对象抛出,打印输出信息到控制台了。int c = a / b;System.out.println(a + "/" + b + "=" + c);// 此处运行也会创建一个:ArithmeticException类型的异常对象。System.out.println(100 / 0);}
}

2、java语言中异常是以什么形式存在的呢?

异常在java中以 的形式存在,每一个 异常类 都可以创建 异常对象

eg.

public class ExceptionTest02 {public static void main(String[] args) {// 通过“异常类”实例化“异常对象”NumberFormatException nfe = new NumberFormatException("数字格式化异常!");// java.lang.NumberFormatException: 数字格式化异常!System.out.println(nfe);}
}

3、异常继承结构图

  • Exception的直接子类:编译时异常(要求程序员在编写程序阶段必须预先对这些异常进行处理,如果不处理编译器报错,因此得名编译时异常。)。
  • RuntimeException:运行时异常。(在编写程序阶段程序员可以预先处理,也可以不管,都行。)

4、异常的分类

异常分为 编译时异常运行时异常

所有异常都是在 运行阶段 发生的。因为只有程序运行阶段才可以 new对象。

因为异常的发生就是 new异常对象

4.1编译时异常因为什么而得名?

因为编译时异常必须在编译(编写)阶段预先处理,如果不处理编译器报错,因此得名。

4.2 编译时异常和运行时异常的区别?

  • 编译时异常一般发生的概率 比较高
  • 运行时异常一般发生的概率 比较低
  • 编译时异常发生概率较高,需要在运行之前对其进行 预处理
  • 运行时异常发生概率较低,没必要提前进行预处理。

4.3编译时异常和运行时异常别称

  • 编译时异常
  1. 受检异常:CheckedException
  2. 受控异常
  • 运行时异常
  1. 未受检异常:UnCheckedException
  2. 非受控异常

1、补充:

public class ExceptionTest03 {public static void main(String[] args) {System.out.println(100 / 0);// 这里的HelloWorld没有输出,没有执行。System.out.println("Hello World!");}
}

程序执行到System.out.println(100 / 0);
此处发生了 ArithmeticException 异常,底层 new 了一个ArithmeticException异常对象,然后抛出了。
由于是 main方法 调用了100 / 0,所以这个异常ArithmeticException抛给了main方法
main方法没有处理,将这个异常自动抛给了 JVMJVM最终终止程序的执行

此时System.out.println("Hello World!");并不会执行。

注意:
ArithmeticException 继承 RuntimeException,属于 运行时异常。在编写程序阶段不需要对这种异常进行预先的处理。


eg.

public class ExceptionTest04 {public static void main(String[] args) {// main方法中调用doSome()方法// 因为doSome()方法声明位置上有:throws ClassNotFoundException// 我们在调用doSome()方法的时候必须对这种异常进行预先的处理。// 如果不处理,编译器就报错。//编译器报错信息: Unhandled exception: java.lang.ClassNotFoundExceptiondoSome();}/*** doSome方法在方法声明的位置上使用了:throws ClassNotFoundException* 这个代码表示doSome()方法在执行过程中,有可能会出现ClassNotFoundException异常。* 叫做类没找到异常。这个异常直接父类是:Exception,所以ClassNotFoundException属于编译时异常。* @throws ClassNotFoundException*/public static void doSome() throws ClassNotFoundException{System.out.println("doSome!!!!");}
}

解决方法一、throws上报给方法调用者(推卸责任:调用者知道)

public class ExceptionTest04 {public static void main(String[] args) throws ClassNotFoundException {doSome();}public static void doSome() throws ClassNotFoundException{System.out.println("doSome!!!!");}
}

解决方法二、try…catch捕捉,处理(调用者是不知道)

public class ExceptionTest04 {public static void main(String[] args) {try {doSome();} catch (ClassNotFoundException e) {e.printStackTrace();}}public static void doSome() throws ClassNotFoundException{System.out.println("doSome!!!!");}
}

5、异常的处理方式

5.1 throws

在方法声明的位置上使用 throws 关键字抛出,谁调用我这个方法,我就抛给谁。抛给 调用者 来处理。

这种处理异常的态度:上报

5.2 try…catch

这个异常不会上报,自己把这个事儿处理了。
异常抛到此处为止,不再上抛了。

注意:

  • 只要异常没有捕捉,采用上报的方式,此方法的 后续代码不会执行
  • try语句块中的某一行出现异常,该行 后面的代码不会执行
  • try…catch捕捉异常之后,后续代码可以执行。

eg.

private static void m1() throws FileNotFoundException {System.out.println("m1 begin");m2();// 以上代码出异常,这里是无法执行的。System.out.println("m1 over");
}
try {m1();// m1方法出异常,下面代码不执行。System.out.println("hello world!");//不执行
} catch (FileNotFoundException e){ //异常处理System.out.println("出异常了!!");System.out.println(e);
}
System.out.println("hello world"); //会执行

注意:

  • 异常发生之后,如果我选择了上抛,抛给了我的调用者,调用者需要对这个异常继续处理,那么调用者处理这个异常同样有两种处理方式。
  • 一般不建议在main方法上使用throws,因为这个异常如果真正的发生了,一定会抛给JVM。JVM只有终止。
  • 一般main方法中的异常建议使用try…catch进行捕捉。

注意:

try {} catch (ClassNotFoundException e) {e.printStackTrace();
}

这个分支中可以使用e引用,e引用 保存的内存地址是那个new出来 异常对象的内存地址


6、在以后开发中,处理编译时异常,应该上报还是捕捉呢?

  • 如果希望调用者来处理,选择throws上报。
  • 其它情况使用捕捉的方式。

7、深入try…catch

  1. catch后面的小括号中的类型可以是 具体的异常类型,也可以是该异常类型的 父类型
  2. catch可以写多个。建议catch的时候,精确的一个一个处理。这样有利于程序的调试。
  3. catch写多个的时候,从上到下,必须遵守 从小到大

eg.

try {FileInputStream fis = new FileInputStream("D:\\Download\\Javabean-addperson案例解析.docx");
} catch(FileNotFoundException e) {System.out.println("文件不存在!");
}等同于try {FileInputStream fis = new FileInputStream("D:\\Download\\Javabean-addperson案例解析.docx");
} catch(Exception e) {// 多态:Exception e = new FileNotFoundException();System.out.println("文件不存在!");
}
try {FileInputStream fis = new FileInputStream("D:\\Download\\Javabean-addperson案例解析.docx");fis.read();
} catch(IOException e){System.out.println("读文件报错了!");
} catch(FileNotFoundException e) {System.out.println("文件不存在!");
}
  1. JDK8的新特性:
    catch() 异常间可以自小到大| 分割

eg.

try {//创建输入流FileInputStream fis = new FileInputStream("D:\\Download\\Javabean-addperson案例解析.docx");// 进行数学运算System.out.println(100 / 0); // 这个异常是运行时异常,编写程序时可以处理,也可以不处理。
} catch(FileNotFoundException | ArithmeticException | NullPointerException e) {System.out.println("文件不存在?数学异常?空指针异常?都有可能!");
}

8、异常两个重要方法

方法名 作用
String getMessage() 返回异常的详细消息字符串
void printStackTrace() 追踪堆栈异常信息(采用异步线程)

9、finally字句

在finally子句中的代码是最后执行的,并且是 一定会执行 的,即使try语句块中的代码出现了异常。

finally子句必须和try一起出现,不能单独编写。

9.1 finally语句通常使用在哪些情况下呢?

通常在finally语句块中完成 资源的释放/关闭

eg.

public class ExceptionTest10 {public static void main(String[] args) {FileInputStream fis = null; // 声明位置放到try外面。这样在finally中才能用。try {fis = new FileInputStream("D:\\Download\\Javabean-addperson案例解析.docx");String s = null;// 这里一定会出现空指针异常!s.toString();System.out.println("hello world!");// 流使用完需要关闭,因为流是占用资源的。// 即使以上程序出现异常,流也必须要关闭!// 放在这里有可能流关不了。//fis.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch(IOException e){e.printStackTrace();} catch(NullPointerException e) {e.printStackTrace();} finally {System.out.println("hello 浩克!");// 流的关闭放在这里比较保险。// finally中的代码是一定会执行的。// 即使try中出现了异常!if (fis != null) { // 避免空指针异常!try {// close()方法有异常,采用捕捉的方式。fis.close();} catch (IOException e) {e.printStackTrace();}}}}
}

9.2try和finally联用,没有catch

eg.

public class ExceptionTest11 {public static void main(String[] args) {try {System.out.println("try...");return;} finally {System.out.println("finally...");}// 这里不能写语句,因为这个代码是无法执行到的。//System.out.println("Hello World!");}
}

以下代码的执行顺序:

  1. 先执行try…
  2. 再执行finally…
  3. 最后执行 return (return语句只要执行方法必然结束。)

注意:

  • try不能单独使用。
  • try finally可以联合使用。
  • 放在finally语句块中的代码是一定会执行的

9.3 finally子句失效

System.exit(0); 只有这个可以治finally。

public class ExceptionTest12 {public static void main(String[] args) {try {System.out.println("try...");// 退出JVMSystem.exit(0); // 退出JVM之后,finally语句中的代码就不执行了!} finally {System.out.println("finally...");}}
}

9.4 finally面试题

public class ExceptionTest13 {public static void main(String[] args) {int result = m();System.out.println(result); //100}/*java语法规则(有一些规则是不能破坏的,一旦这么说了,就必须这么做!):java中有一条这样的规则:方法体中的代码必须遵循自上而下顺序依次逐行执行(亘古不变的语法!)java中海油一条语法规则:return语句一旦执行,整个方法必须结束(亘古不变的语法!)*/public static int m(){int i = 100;try {// 这行代码出现在int i = 100;的下面,所以最终结果必须是返回100// return语句还必须保证是最后执行的。一旦执行,整个方法结束。return i;} finally {i++;}}
}

反编译之后的效果:

public static int m(){int i = 100;int j = i;i++;return j;
}

9.5 final finally finalize有什么区别?

  • final 关键字
  1. final修饰的无法继承
  2. final修饰的方法无法覆盖
  3. final修饰的变量不能重新赋值
  • finally 关键字
  1. finally 和try一起联合使用。
  2. finally语句块中的代码是必须执行的。
  • finalize 标识符
  1. 是一个Object类中的方法名。
  2. 这个方法是由垃圾回收器GC负责调用的

10、自定义异常(开发中常用)

10.1前言

SUN提供的JDK内置的异常肯定是不够的用的。在实际的开发中,有很多业务,这些业务出现异常之后,JDK中都是没有的。和业务挂钩的。因此需要自定义异常。

10.2自定义异常步骤

  1. 第一步:编写一个类继承 Exception 或者 RuntimeException.
  2. 第二步:提供两个 构造方法,一个无参数的,一个带有String参数的。

eg.

//栈操作异常:自定义异常!
public class StackOperationException extends Exception{ // 编译时异常!public MyStackOperationException(){}public MyStackOperationException(String s){super(s);}
}

11、方法覆盖,时遗留的问题

  • 重写之后的方法不能比重写之前的方法抛出更多(更宽泛)的异常,可以更少。方法覆盖
class Animal {public void doSome(){}public void doOther() throws Exception{}
}class Cat extends Animal {// 编译正常。public void doSome() throws RuntimeException{}// 编译报错。/*public void doSome() throws Exception{}*/// 编译正常。/*public void doOther() {}*/// 编译正常。/*public void doOther() throws Exception{}*/// 编译正常。public void doOther() throws NullPointerException{}
}

注意:
一般不会这样考虑,方法覆盖复制一份,然后重写就好了。

12、总结异常中的关键字

  • 异常捕捉:
  1. try
  2. catch
  3. finally
  • throws 在方法声明位置上使用,表示上报异常信息调用者
  • throw 手动抛出异常

eg.

    public void pop() throws StackOperationException {if(index < 0){throw new MyStackOperationException("弹栈失败,栈已空!");//手动抛出异常}}

该方法index < 0时手动抛出异常,然后在方法里没有处理,上报给调用者,让调用者处理!

Java异常(超详细!)相关推荐

  1. 微信公众号支付开发步骤Java(超详细)

    做为一个刚刚做完微信公众号的小白,我不得不吐槽一下微信给的官方文档,里面那坑一个接一个,我这是跳进去再爬出来,一下给做了四天,本来技术就不够好,还被文档带的跑偏跑偏...我在这给大家整理一份超级详细的 ...

  2. 拼图游戏(JAVA)超详细!入股不亏

    哎,最近被这个搞的头晕眼花的,烦死了!!! 不多解释了,代码注释很详细(毕竟写了好几天还熬了个大✌夜),不会欢迎私聊(虽然本人JAVA真的拉) MainJFrame.java//主窗体(package ...

  3. Java多线程超详细总结

    目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么 ...

  4. 实战 本地服务器Confluence 7.13部署 一篇就够(从0开始安装配置 Debian11 + Mysql + Java)超详细

    前言 在公司用了好几年的Confluence (WIKI),不说他有多方便吧,主要是习惯了操作方式.最近被封在家里,就想着趁时间比较充裕就在家里部署一套Confluence,1是为了把自己平时的学习P ...

  5. Java简介超详细整理,适合新手入门

    目录 一.Java 简介 二.Oracle 公司 三.Java平台体系 四.Java语言主要特点 1.Java 语言是简单的 2.Java 语言是面向对象的 3.Java语言是分布式的 4.Java ...

  6. 超详细的Java面试题总结(四 )之JavaWeb基础知识总结

    系列文章请查看: 超详细的Java面试题总结(一)之Java基础知识篇 超详细的Java面试题总结(二)之Java基础知识篇 超详细的Java面试题总结(三)之Java集合篇常见问题 超详细的Java ...

  7. Java并发知识总结,超详细!(上)

    Java并发知识总结,超详细! 首先给大家分享一个github仓库,上面放了 200多本经典的计算机书籍 ,包括C语言.C++.Java.Python.前端.数据库.操作系统.计算机网络.数据结构和算 ...

  8. 超详细的Java面试题总结(二)之Java基础知识篇

    系列文章: 超详细的Java面试题总结(一)之Java基本知识 超详细的Java面试题总结(二)之Java基础知识篇 超详细的Java面试题总结(三)之Java集合篇常见问题 超详细的Java面试题总 ...

  9. Java并发编程Future超详细教程

    非原创,自己保存学习用,传播请参考原文. 原文链接:Java并发编程Future超详细教程 前言 创建线程有几种方式?这个问题的答案应该是可以脱口而出的吧 继承 Thread 类实现 Runnable ...

最新文章

  1. 查看python解释器安装路径
  2. 沙市一中2021年高考成绩查询,2021年荆州高考状元名单公布,荆州文理科状元是谁多少分...
  3. 《面向对象分析与设计》读书笔记——第一章 复杂性
  4. 精品思维导图,流程图模板分享
  5. 【论文解读】PFLD:高精度实时人脸关键点检测算法
  6. linux, configure --prefix=/有什么用
  7. 程序语言基础:解释程序基本原理笔记
  8. acctype mysql assoc_DedeCMS V5.3二次开发经验分享
  9. WebService生成客户端代理的工具WSDL参数介绍
  10. html td中加label,html – td对齐内的2个标签
  11. 2021高考成绩查询截图,科目四2021模拟考试成绩截图
  12. 计算机操作系统笔记(四)
  13. 大华电子秤客户端开发文档_『飞桨』全流程开发工具PaddleX
  14. go技术文章梳理(2018)
  15. Matlab遥感图像分波段,组合显示
  16. Mac安装使用kettle
  17. 【AI Studio】飞桨图像分类零基础训练营 - 03 - 卷积神经网络基础
  18. 【CSS如何画简单的三角形或者梯形】
  19. 灵猫二维码 - 二维码中间加图片的方法
  20. html5画直线箭头,HTML5 canvas画带箭头的虚线

热门文章

  1. 经验分享:SEO新手面对新网站应该如何去优化
  2. 计算机三级数据库技术知识点
  3. 电子宠物门的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  4. iPhone电池充放电循环次数的计算说明
  5. 【面试练习题】使用编程语言输出1900年~2000年的全部闰年
  6. jsonpath 判断是否包含_JsonNode findPath方法详解 JsonNode判断是否为空详解
  7. 计算机创新大赛参赛表,计算机科学学院 “互联网+”大学生创新创业大赛师生参赛奖励办法...
  8. 【用VSCode编写MarkDown并导出Epub电子书】
  9. 如何自制地形纹理贴图
  10. Surface RT and Surface Pro