Java常见踩坑记录之异常处理

目录
  • 一、Java异常类层次结构
  • 二、Throwable类常用方法
  • 三、try-catch-finally
  • 四、使用 try-with-resources 来代替try-catch-finally
  • 五、自定义异常
  • 总结

一、Java异常类层次结构

Java中,所有的异常都来源于java.lang包中的Throwable类,它有两个重要的子类,Exception(异常)和Error(错误)。

  • Exception :程序本身可以处理的异常,可以通过 catch 来进行捕获。Exception 又可以分为 受检查异常(必须处理) 和 不受检查异常(可以不处理)。
  • Error :Error 属于程序无法处理的错误 ,我们没办法通过 catch 来进行捕获 。例如,虚拟机内存不够错误(OutOfMemoryError)、类定义错误(NoClassDefFoundError)等 。这些异常发生时,Java 虚拟机(JVM)一般会线程终止。

二、Throwable类常用方法

  • public String getMessage(): 返回异常发生时的简要描述
  • public String toString(): 返回异常发生时的详细信息
  • public String getLocalizedMessage():返回异常对象的本地化信息。使用 Throwable 的子类覆盖这个方法,可以生成本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与 getMessage()返回的结果相同
  • public void printStackTrace():在控制台上打印 Throwable 对象封装的异常信息

三、try-catch-finally

  • try块: 用于捕获异常。其后可接零个或多个 catch 块,如果没有 catch 块,则必须跟一个 finally 块。
  • catch块: 用于处理 try 捕获到的异常。
  • finally 块: 无论是否捕获或处理异常,finally 块里的语句都会被执行。当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行。

在以下 2种特殊情况下,finally 块不会被执行:

  • 在 try 或 finally块中用了 System.exit(int)退出程序。但是,如果 System.exit(int) 在异常语句之后,finally 还是会被执行
  • 程序所在的线程死亡。

代码示例:

BufferedReader br = null;
try {
    br = new BufferedReader(new FileReader("test.txt"));
    br.readLine();
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if (br != null)
        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
}

四、使用 try-with-resources 来代替try-catch-finally

1. 适用范围(资源的定义): 任何实现 java.lang.AutoCloseable 的对象

2. 关闭资源和 finally 块的执行顺序:try-with-resources 语句中,任何 catch 或 finally 块在声明的资源关闭后运行

《Effecitve Java》中明确指出:

面对必须要关闭的资源,我们总是应该优先使用 try-with-resources 而不是try-finally。随之产生的代码更简短,更清晰,产生的异常对我们也更有用。try-with-resources语句让我们更容易编写必须要关闭的资源的代码,若采用try-finally则几乎做不到这点。

将上面的代码例子改造:

try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
    br.readLine();
} catch (Exception e) {
    e.printStackTrace();
}

代码变得非常简洁。

注意:try-with-resource中声明的变量会隐式的加上final 关键字,所以无法再进行赋值。

五、自定义异常

在Java中要想创建自定义异常,需要继承Throwable或者他的子类Exception。

因为父类已经把异常信息的操作都完成了,所在子类只要在构造时,将异常信息传递给父类通过super 语句即可。

代码示例:

public class CustomException extends Exception {

	//无参构造方法
	public CustomException(){

		super();
	}

	//有参的构造方法
	public CustomException(String message){
		super(message);

	}

	// 用指定的详细信息和原因构造一个新的异常
	public CustomException(String message, Throwable cause){

		super(message,cause);
	}

	//用指定原因构造一个新的异常
	 public CustomException(Throwable cause) {

		 super(cause);
	 }

}

按照国际惯例,自定义的异常应该总是包含如下的构造函数:

  • 一个无参构造函数
  • 一个带有String参数的构造函数,并传递给父类的构造函数。
  • 一个带有String参数和Throwable参数,并都传递给父类构造函数
  • 一个带有Throwable 参数的构造函数,并传递给父类的构造函数。

finally块和return

首先一个不容易理解的事实:在 try块中即便有return,break,continue等改变执行流的语句,finally也会执行。

finally中的return 会覆盖 try 或者catch中的返回值。

finally中的return或异常会抑制(消灭)前面try或者catch块中的异常。

总结

到此这篇关于Java常见踩坑记录之异常处理的文章就介绍到这了,更多相关Java常见异常处理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java学习之JasperReport踩坑

    下面进入正题,来介绍下今天的猪脚JasperReport或者叫它ireport亦或jasperstudio,当然后面两个是它的可视化工具. JasperReport是个什么东西? 这货其实在国内用户也不少,是个国外的产品,而且可以说在JAVA报表领域应用是相当的广泛. 我当初刚刚接触这个报表的时候还是相当的喜欢的,最主要的是它的可视化工具,真的是让我欲罢不能,竟然可以通过简单画图的方式来设计JAVA报表.说起画图就是可以通过可视化的工具,让我们可视化的设计报表模板,并且它支持输出的文件格式很广泛

  • 一不小心就让Java开发踩坑的fail-fast是个什么鬼?(推荐)

    我在<为什么阿里巴巴禁止在 foreach 循环里进行元素的 remove/add 操作>一文中曾经介绍过Java中的fail-fast机制,但是并没有深入介绍,本文,就来深入介绍一下fail-fast. 什么是fail-fast 首先我们看下维基百科中关于fail-fast的解释: In systems design, a fail-fast system is one which immediately reports at its interface any condition that

  • java使用BeanUtils.copyProperties踩坑经历

    1. 原始转换 提起对象转换,每个程序员都不陌生,比如项目中经常涉及到的DO.DTO.VO之间的转换,举个例子,假设现在有个OrderDTO,定义如下所示: public class OrderDTO { private long id; private Long userId; private String orderNo; private Date gmtCreated; // 省略get.set方法 } 有个OrderVO,定义如下所示: public class OrderVO { pr

  • Java踩坑记录之BigDecimal类

    前言 在java.math包中提供了对大数字的操作类,用于进行高精确计算,如BigInteger,BigDecimal类.而平常我们开发中使用最多的float和double只能适用于一般的科学和工程计算,如果要在比较精确的计算方面如货币,那么使用float和double会相应的丢失精度,因此用于精密计算大数字的类BigDecimal就必不可少了.所以BigDecimal适合商业计算场景,用来对超过16位有效位的数进行精确的运算.但是BigDecimal的使用并不像float和double那样,使

  • Java中数组协变和范型不变性踩坑记录

    前言 变性是OOP语言不变的大坑,Java的数组协变就是其中的一口老坑.因为最近踩到了,便做一个记录.顺便也提一下范型的变性. 解释数组协变之前,先明确三个相关的概念,协变.不变和逆变. 下面话不多说了,来一起看看详细的介绍吧 一.协变.不变.逆变 假设,我为一家餐馆写了这样一段代码 class Soup<T> { public void add(T t) {} } class Vegetable { } class Carrot extends Vegetable { } 有一个范型类Sou

  • Java踩坑记录之Arrays.AsList

    前言 java.util.Arrays的asList方法可以方便的将数组转化为集合,我们平时开发在初始化ArrayList时使用的比较多,可以简化代码,但这个静态方法asList()有几个坑需要注意: 一. 如果对集合使用增加或删除元素的操作将会报错 如下代码: List list = Arrays.asList("a","b","c"); list.add("d"); 输出结果: Exception in thread &q

  • Java List的remove()方法踩坑

    目录 1.普通for循环遍历List删除指定元素--错误!!! 2.for循环遍历List删除元素时,让索引同步调整--正确! 3.倒序遍历List删除元素--正确! 4.foreach遍历List删除元素--错误!!! 5.迭代删除List元素--正确! 6.迭代遍历,用list.remove(i)方法删除元素--错误!!! 7.List删除元素时,注意Integer类型和int类型的区别. 总结: Java的List在删除元素时,一般会用list.remove(o)/remove(i)方法.

  • java8 stream的多字段排序实现(踩坑)

    关于java8 的stream排序用法这里不做多说,这里介绍下曾经在多字段排序时遇到过的一个坑. 需求:需要根据id去分组,然后取出每组中行号最大的一个对象值. 想到可以利用stream的多字段排序,先按id去排,再看行号去排,demo代码如下: class Tt{ private int id; private int line; public Tt(int id, int line) { this.id = id; this.line = line; } public int getId()

  • Java十道入门易踩坑题分析前篇

    目录 1,java基本类型 2,java包装类 3,Java编译 4,JDK,JVM,JRE 5,类型转换 6,转义字符 7,标识符 8,类型转换 9,赋值符号 10,打印一个字符串 1,java基本类型 下面属于java基本数据类型的有( ) A.String B.byte C.char D.Array Java基本数据类型分为三种,数值型,字符型,布尔型 数值型: 整型:byte.short.int.long 浮点型:double.float 字符型:char 布尔型:boolean Arr

  • Java常见踩坑记录之异常处理

    目录 一.Java异常类层次结构 二.Throwable类常用方法 三.try-catch-finally 四.使用 try-with-resources 来代替try-catch-finally 五.自定义异常 总结 一.Java异常类层次结构 Java中,所有的异常都来源于java.lang包中的Throwable类,它有两个重要的子类,Exception(异常)和Error(错误). Exception :程序本身可以处理的异常,可以通过 catch 来进行捕获.Exception 又可以

  • Java中Objects.equals踩坑记录

    目录 前言 1. 案发现场 2. 判断相等的方法 2.1 使用==号 2.2 使用equals方法 3. 空指针异常 4. Objects.equals的作用 5. Objects.equals的坑 总结 前言 最近review别人代码的时候,发现有个同事,在某个业务场景下,使用Objects.equals方法判断两个值相等时,返回了跟预期不一致的结果,引起了我的兴趣. 原本以为判断结果会返回true的,但实际上返回了false. 记得很早之前,我使用Objects.equals方法也踩过类似的

  • python中remove函数的踩坑记录

    摘要: 在python的使用过程中,难免会遇到要移除列表中对象的要求.这时可以使用remove函数. 对于python中的remove()函数,官方文档的解释是:Remove first occurrence of value.大意也就是移除列表中等于指定值的第一个匹配的元素. 语法 list.remove() 参数 obj 参数:从列表中删除的对象的索引 返回值 删除后不会返回值 常见用法: a = [1,2,3,4],a.remove(1),然后a就是[2,3,4]:对于a = [1,1,1

  • SpringMVC中文乱码踩坑记录

    目录 问题 问题根源 解决方案 方案一 方案二 问题 使用SpringMVC在返回一个字符串时发生了中文乱码问题.produces属性无效 @RequestMapping(value = "/nihao", produces = "text/plain;charset=UTF-8") @ResponseBody public String hello(HttpServletResponse response) throws UnsupportedEncodingEx

  • JavaWeb踩坑记录之项目访问不到html文件

    踩坑问题和原因 踩坑问题 由于博主的JavaWeb是速成所以对一些知识点掌握的不是很熟,所以也就出现了今天这个问题——Tomcat访问不到html文件. 在运行是总是会出现404.每次出现这个就很烦,让人摸不着头脑.虽然这个问题其实对一些项目没有很大的影响,但是他会让我的项目目录会很杂乱.总的来说该问题就是不解决它,就会出现一堆静态资源都在一个文件夹.这可能会导致后期找一些项目的文件就得找半天. 踩坑原因 由于粗心的我把一些html文件都放在WEB-INF下面.因为WEB-INF下的资源不能直接

  • vue2.x background:url()的踩坑记录

    目录 background:url()的踩坑记录 backgroundImage路径问题 处理方法 background:url()的踩坑记录 开发模式下vue中background: url(‘../../assets/img/xxxxx’)直接写在行间样式不生效,即不能直接在标签中style属性中写, 必须写在非行间样式才会生效. 如果要写在行间样式中,需要对资源进行导入,比如ES规范的import或者CommomJS规范的require backgroundImage路径问题 项目中图片都

  • Spring Data JPA踩坑记录(@id @GeneratedValue)

    目录 Spring Data JPA踩坑记录 JPA踩坑:No property xxx found for type xxx 问题发现 问题解决 Spring Data JPA踩坑记录 最近在做自己的一个项目时 使用了spring jpa 由于数据库用的是mysql 在给实体类entity 的id给注解时@Id遇到了一个坑 自己找了许久才在stackoverflow 上找到了答案 注意 再查询数据库的时候并不会因此报错 而当你的主键是自增的时候 在添加数据的时候就会报错了 看看我们的实体类 注

  • react中使用useEffect及踩坑记录

    目录 使用useEffect及踩坑记录 useEffect 介绍 useEffect常见跳坑 hooks中useEffect()使用总结 常见使用 useEffect() 的第二个参数说明 useEffect() 第一个函数参数的返回值 useEffect() 的注意点 使用useEffect及踩坑记录 useEffect 介绍 useEffect时reactHook中最重要,最常用的hook之一. useEffect相当于react中的什么生命周期呢? 这个问题在react官网中有过介绍,在使

随机推荐