【Java】如何理解Java中的异常机制?

1 异常的概念

  1. 程序在执行过程中出现非正常线性,导致JVM非正常停止
  2. 异常不是语法错误

2 异常的分类

  1. Throwable是所有错误或异常的超类
  2. ··········Exception是编译期间异常(写代码时IDE会报错)
  3. ····················RuntimeException时运行期异常,程序运行时出现的问题
  4. ··········Error错误 必须修改代码才能继续执行

3 异常的产生过程

  1. 例如在某个方法体中,代码的不当操作导致了异常,运行程序时,JVM会检测出异常。
  2. JVM会根据异常产生的原因创建一个异常对象,包含异常产生的内容、原因和位置。
  3. 如果程序的方法体中没有在try-catch中定义异常处理逻辑,那么JVM就会把异常对象抛出给调用者该方法的main来处理这个异常。
  4. JVM接收到异常对象以红色字体打印在控制台并终止程序。(中断处理)

4 处理异常的方式

  1. throws虚拟机处理异常:中断程序,抛出错误,打印在控制台
  2. try-catch自己定义异常处理逻辑:程序可以继续执行

4.1 throw关键字

作用:在指定方法中抛出指定异常

使用格式:throw new xxxException(“异常产生原因”)

注意事项

  • 必须写在方法内部
  • new的对象要是Exception 或 Exception的子类
  • 如果抛出指定的异常对象,必须处理这个异常对象。
  • 如果创建的时RuntimeException或其子类,默认交给JVM处理(打印异常对象,中断程序)
  • 如果创建的时编译异常,就必须处理这个异常,必须throws或者try-catch

小贴士:必须首先对方法传递来的参数进行合法性校验,如果参数不合法,必须抛出异常,告知方法调用者,传递的参数有问题。

示例
运行时异常:NullPointerException

public class ThrowException {public static void main(String[] args) {
//      int[] arr = null;int arr [] = {1,2,3};int element = getElement(arr, 10);System.out.println(element);}public static int getElement(int[] arr, int index){if(arr == null){throw new NullPointerException("传递的数组值是null");//空指针异常是运行期异常 默认交给JVM处理}if(index < 0 || index > arr.length){throw new ArrayIndexOutOfBoundsException("数组越界");}//运行期异常int element = arr[index];return element;}
}

在这里插入图片描述

4.2 Objects非空判断

Objects类的静态方法

public static <T> T requireNonNull(T obj) {if (obj == null)throw new NullPointerException()  ;return obj;
}

简化非空判断

public static void main(String[] args) {method(null);}public static void method(Object obj){Objects.requireNonNull(obj,"传递对象为空");}

4.3 throws声明异常

异常处理的第一种方式,交给别人处理

作用:当方法内部抛出异常对象时,必须处理异常对象,可以使用throws关键字处理,会把异常对象抛给方法调用者处理,自己不处理,交给他人处理,最终交给JVM处理。(JVM中断处理

使用方式:在方法声明时使用

注意

  • 必须写在方法声明处
  • 必须是Exception或其子类
  • 抛出多个异常,声明处要声明多个异常,如果是父子异常,声明父异常即可
  • 调用了声明异常的方法必须处理声明的异常。throws抛出最终交给JVM处理或者try-catch定义异常处理逻辑。

编译时异常:FileNotFoundException

    public static void main(String[] args) throws FileNotFoundException {method("c:\\d.txt");}public static void method(String filename) throws FileNotFoundException {if(!filename.equals("c:\\\\a.txt")){throw new FileNotFoundException("文件路径错误");}}

在这里插入图片描述


FileNotFoundException extends IOException extends Exception

    public static void main(String[] args) throws IOException {readFile("c:\\a.doc");}public static void readFile(String filename) throws IOException {if(!filename.endsWith(".txt")){throw new IOException("文件后缀不对");}}

在这里插入图片描述

4.4 try-catch捕获异常

异常处理的第二种方式,自己处理,程序不中断

public static void main(String[] args) throws IOException {try{readFile("d:\\a.tx");}catch (IOException e){System.out.println("文件后缀有误");}System.out.println("程序不中断,后续代码继续执行");}public static void readFile(String filename) throws IOException{if(!filename.endsWith(".txt")){throw new IOException("文件后缀有误");}System.out.println("读取文件");}

4.5 Throwable类中三个异常处理方法

  • String getMessage()

打印Message: throw new IOException(Message);

public static void main(String[] args) {try{readFile("d:\\a.tx");}catch (IOException e){System.out.println(e.getMessage());}System.out.println("程序不中断,后续代码继续执行");}public static void readFile(String filename) throws IOException{if(!filename.endsWith(".txt")){throw new IOException("文件后缀有误");}System.out.println("读取文件");}

在这里插入图片描述


  • String toString()

重写Object类的toString

public static void main(String[] args){try{readFile("d:\\a.tx");}catch (IOException e){System.out.println(e.toString());}System.out.println("程序不中断,后续代码继续执行");}public static void readFile(String filename) throws IOException{if(!filename.endsWith(".txt")){throw new IOException("文件后缀有误");}System.out.println("读取文件");}

在这里插入图片描述


  • void printStackTrace()
public static void main(String[] args) {try{readFile("d:\\a.tx");}catch (IOException e){e.printStackTrace();}System.out.println("程序不中断,后续代码继续执行");}public static void readFile(String filename) throws IOException{if(!filename.endsWith(".txt")){throw new IOException("文件后缀有误");}System.out.println("读取文件");}

在这里插入图片描述

4.6 finally代码块

public static void main(String[] args){try {readFile("d:\\a.tx");} catch (IOException e) {e.printStackTrace();} finally {System.out.println("异常出现后依旧需要执行的代码");}System.out.println("程序不中断,后续代码继续执行");}public static void readFile(String filename) throws IOException{if(!filename.endsWith(".txt")){throw new IOException("文件后缀有误");}System.out.println("读取文件");}

4.7 多异常捕获

分别捕获,分别处理

public static void main(String[] args) {int[] arr = {1,2,3};List<Integer> list = new ArrayList<>();list.add(1);try{System.out.println(arr[3]);}catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();}try{System.out.println(list.get(1));}catch (IndexOutOfBoundsException e){e.printStackTrace();}System.out.println("后续代码继续执行...");}

在这里插入图片描述


一次捕获,多次处理

public static void main(String[] args) {try{int[] arr = {1,2,3};List<Integer> list = new ArrayList<>();System.out.println(arr[3]);list.add(1);System.out.println(list.get(1));}catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();}catch (IndexOutOfBoundsException e){e.printStackTrace();}System.out.println("后续代码继续执行...");}

在这里插入图片描述
注意事项:一个try多个catch,catch中的异常变量如果有父子关系,子类异常变量必须写在上面,否则会报错。(XXXException has already been caught)


一次捕获,一次处理

public static void main(String[] args) {try {int[] arr = {1, 2, 3};List<Integer> list = new ArrayList<>();System.out.println(arr[3]);list.add(1);System.out.println(list.get(1));}catch (Exception e){e.printStackTrace();}System.out.println("后续代码继续执行...");}

运行时异常被抛出可以不处理。即不捕获也不声明抛出。

如果finally有return语句,永远返回finally中的结果,避免该情况。

如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常。

父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理【try-catch】,不能声明抛出。

5 自定义异常

  • 自定义异常类一部都是以Exception结尾
  • 必须继承Exception(编译期异常,要么try-catch要么throws)或者继承RuntimeException(运行期异常交给JVM中断处理)

模拟注册操作

  1. 定义异常类 继承Exception
public class RegisterException extends Exception {public RegisterException() {super();}public RegisterException(String message) {super(message);}
}
  1. 定义测试类

throws

public class Register {static String[] usernames = {"张三","李四","王五"};public static void main(String[] args) throws RegisterException {System.out.print("请输入待注册用户名:");Scanner sc = new Scanner(System.in);String username = sc.next();checkUserName(username);System.out.println("恭喜,注册成功!");}//继承Exception是编译期异常 throws 处理public static void checkUserName(String name) throws RegisterException {for(String n: usernames){if(n.equals(name)){throw new RegisterException("该用户名已注册");}}}
}

try-catch

public class Register {static String[] usernames = {"张三", "李四", "王五"};public static void main(String[] args) {System.out.print("请输入待注册用户名:");Scanner sc = new Scanner(System.in);String username = sc.next();try {checkUserName(username);} catch (RegisterException e) {e.printStackTrace();return;}System.out.println("恭喜,注册成功!");}//继承Exception是编译期异常 throws 处理public static void checkUserName(String name) throws RegisterException {for(String n: usernames){if(n.equals(name)){throw new RegisterException("该用户名已注册");}}}
}


  1. 定义异常类 继承自RuntimeException
public class RegisterException extends RuntimeException {public RegisterException() {super();}public RegisterException(String message) {super(message);}
}
  1. 定义测试类:不需要处理运行期异常
public class Register {static String[] usernames = {"张三","李四","王五"};public static void main(String[] args){System.out.print("请输入待注册用户名:");Scanner sc = new Scanner(System.in);String username = sc.next();checkUserName(username);System.out.println("恭喜,注册成功!");}//继承RuntimeExceptionqpublic static void checkUserName(String name) throws RegisterException {for(String n: usernames){if(n.equals(name)){throw new RegisterException("该用户名已注册");//抛出给JVM处理}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/481005.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文本匹配相关方向总结(数据,场景,论文,开源工具)

Motivation 前不久小夕在知乎上写了一个回答《NLP有哪些独立研究方向》&#xff0c;于是有不少小伙伴来问分类和匹配的参考资料了&#xff0c;鉴于文本分类的资料已经超级多了&#xff0c;就不写啦&#xff08;不过分类相关的tricks可以看之前写的这篇文章《文本分类重要tricks…

机器学习】LDA线性判别分析

【机器学习】LDA线性判别分析1. LDA的基本思想2. LDA求解方法3. 将LDA推广到多分类4. LDA算法流程5. LDA和PCA对比【附录1】瑞利商与广义瑞利商线性判别分析 (Linear Discriminant Analysis&#xff0c;LDA)是一种经典的线性学习方法&#xff0c;在二分类问题上因为最早由[Fish…

科普 | 动态本体简介

本文转载自知乎专栏知识图谱和智能问答。 1 近年来&#xff0c;随着语义Web的兴起&#xff0c;本体技术受到了广泛关注。很多大型跨国公司都开始研究本体技术。谷歌于2012年提出了知识图谱的项目&#xff0c;旨在利用本体技术来提高搜索的精度和更智能化的知识浏览。国内的互联…

文本匹配相关方向打卡点总结

Motivation前不久小夕在知乎上写了一个回答《NLP有哪些独立研究方向》[1]&#xff0c;于是有不少小伙伴来问分类和匹配的参考资料了&#xff0c;鉴于文本分类的资料已经超级多了&#xff0c;就不写啦&#xff08;不过分类相关的tricks可以看之前写的这篇文章《文本分类重要tric…

深入理解K-Means聚类算法

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/taoyanqi8932/article/details/53727841 </div><link rel"stylesheet" href"https://csdnimg.cn/release/phoenix/template/css/ck_htmledit…

刘挺 | 从知识图谱到事理图谱

本文转载自 AI科技评论。 在“知识图谱预见社交媒体”的技术分论坛上&#xff0c;哈尔滨工业大学刘挺教授做了题为“从知识图谱到事理图谱”的精彩报告。会后AI科技评论征得刘挺教授的同意&#xff0c;回顾和整理了本次报告的精彩内容。 刘挺教授 刘挺教授的报告内容分为四部分…

我对JVM的理解

一、JVM简介 JVM总体上是由类装载子系统&#xff08;ClassLoader&#xff09;、运行时数据区、执行引擎、内存回收这四个部分组成。 其中我们最为关注的运行时数据区&#xff0c;也就是JVM的内存部分则是由方法区&#xff08;Method Area&#xff09;、JAVA堆&#xff0…

【LeetCode】4月4日打卡-Day20-接雨水

描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图&#xff0c;在这种情况下&#xff0c;可以接 6 个单位的雨水&#xff08;蓝色部分表示雨水&a…

算法与数据结构--空间复杂度O(1)遍历树

大家好~我叫「小鹿鹿鹿」&#xff0c;是本卖萌小屋的第二位签约作&#xff08;萌&#xff09;者&#xff08;货&#xff09;。和小夕一样现在在从事NLP相关工作&#xff0c;希望和大家分享NLP相关的、不限于NLP的各种小想法&#xff0c;新技术。这是我的第一篇试水文章&#xf…

PCA主成分分析学习总结

大概主成分分析&#xff08;Principal components analysis&#xff0c;以下简称PCA&#xff09;是最重要的降维方法之一。在数据压缩消除冗余和数据噪音消除等领域都有广泛的应用。一般我们提到降维最容易想到的算法就是PCA&#xff0c;下面我们就对PCA的原理做一个总结。首先…

技术动态 | 大规模中文概念图谱CN-Probase正式发布

本文转载自公众号知识工场。 历时多年的研发&#xff0c;复旦大学知识工场实验室正式推出大规模中文概念图谱——CN-Probase&#xff0c;用于帮助机器更好的理解人类语言。概念图谱中包含实体&#xff08;比如“刘德华”&#xff09;、概念&#xff08;比如“演员”&#xff09…

生产Docker应用重启排查经历

一、现象描述 近期&#xff0c;生产云平台监控发生Docker应用重启次数过多事故报警&#xff0c;经观察发现某些Docker应用不定期地出现重启现象&#xff0c;已严重影响服务正常提供 生产应用重启的判断条件&#xff1a;健康检查连续3次检查不通过 生产健康检查间隔时间设置为…

【Java】深入理解Java线程

1 相关概念 并发&#xff1a;两个或多个事件在同一时间段内发生【多个任务交替执行】 并行&#xff1a;两个或多个事件在同一时刻发生【多个任务同时执行】 进程&#xff1a;进入内存的程序 内存&#xff1a;所有应用程序都要进入到内存中执行 临时存储RAM 线程&#xff1a;进…

机器学习——多元线性回归分析(multiple regression)及应用

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/loveliuzz/article/details/78006493 </div><link rel"stylesheet" href"https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_vi…

肖仰华 | 知识图谱研究的回顾与展望

本文转载自公众号知识工场。 本文整理自2017年10月19日肖仰华教授在知识图谱前沿技术课程&#xff08;华东师范大学站&#xff09;所做的报告&#xff0c;报告的题目为《知识图谱研究的回顾与展望》。 大家好&#xff0c;很多人在对知识图谱的研究或者落地方面都表现出了极大的…

Java应用性能调优工具介绍及实践

一、背景 &#xff08;1&#xff09;、随着微服务架构的逐渐推广&#xff0c;一个大型的单个应用程序被拆分为数个微服务系统&#xff0c;这为研发人员的本地调试跟踪带来困难 &#xff08;2&#xff09;、在微服务架构中&#xff0c;由于业务的复杂性&#xff0c;常常一个业务…

Google、MS和BAT教给我的面试真谛

大家好呀&#xff0c;我是「小鹿鹿鹿」&#xff0c;我又来啦&#xff5e;&#xff5e;趁大家还有依稀印象赶紧乘热打铁&#xff5e;&#xff5e;这次聊一聊关于面试的一些小想法&#xff0c;希望和大家交流交流&#xff5e;&#xff5e;虽然资历尚浅&#xff0c;但是也面过不少…

AAAI 2018 论文 | 蚂蚁金服公开最新基于笔画的中文词向量算法

导读&#xff1a;词向量算法是自然语言处理领域的基础算法&#xff0c;在序列标注、问答系统和机器翻译等诸多任务中都发挥了重要作用。词向量算法最早由谷歌在2013年提出的word2vec&#xff0c;在接下来的几年里&#xff0c;该算法也经历不断的改进&#xff0c;但大多是仅适用…

甲子光年 | 为什么知识图谱终于火了?

本文转载自公众号甲子光年。如果知识是人类进步的阶梯&#xff0c;知识图谱就是AI进步的阶梯。作者&#xff5c;金丝猴编辑&#xff5c;甲小姐设计&#xff5c;孙佳栋微信&#xff5c;甲子光年 (ID:jazzyear)“知识图谱”相较于AI其他分支&#xff0c;似乎是最后一个热起来的赛…

Java多线程并发编程

一、线程池 1.1、什么是线程池 线程池是一种多线程的处理方式&#xff0c;利用已有线程对象继续服务新的任务&#xff08;按照一定的执行策略&#xff09;&#xff0c;而不是频繁地创建销毁线程对象&#xff0c;由此提高服务的吞吐能力&#xff0c;减少CPU的闲置时间。具体组成…