一篇文章带你深入了解Java异常

目录
  • 一.初识异常
    • 1.常见的异常类型
      • <1>除以0
      • <2>数组下标越界
      • <3>访问null对象
    • 2.防御式编程
      • <1>LBYL
      • <2>EAFP
  • 二.异常的基本用法
    • 1.捕获异常
      • <1>基本语法:
      • <2>try catch代码示例
      • <3>try catch finally代码示例
    • 2.异常的处理流程
    • 3.抛出异常(使用throw关键字)
  • 三.java异常体系
    • 1.java内置异常
    • 2.自定义异常类
  • 总结

一.初识异常

1.常见的异常类型

<1>除以0

System.out.println(10/0);
// 执行结果
Exceptioninthread"main"java.lang.ArithmeticException: /byzero

<2>数组下标越界

int[] arr= {1, 2, 3};
System.out.println(arr[100]);
// 执行结果
Exceptioninthread"main"java.lang.ArrayIndexOutOfBoundsException: 100

<3>访问null对象

publicclassTest {
    publicintnum=10;
    publicstaticvoidmain(String[] args) {
        Testt=null;
        System.out.println(t.num);
    }
}
// 执行结果
Exceptioninthread"main"java.lang.NullPointerException

2.防御式编程

<1>LBYL

Look Before You Leap. 在操作之前就做充分的检查.(先请示,再行动)

<2>EAFP

It's Easier to Ask Forgiveness than Permission. “事后获取原谅比事前获取许可更容易”. 也就是先操作, 遇到问题再处理.(先斩后奏)

二.异常的基本用法

1.捕获异常

<1>基本语法:

try{
有可能出现异常的语句 ;
}[catch (异常类型异常对象) {} ... ]
[finally {
异常的出口}]

注意事项:

1.try 代码块中放的是可能出现异常的代码.

2.catch 代码块中放的是出现异常后的处理行为.

3.finally 代码块中的代码用于处理善后工作, 会在最后执行.

4.其中 catch 和 finally 都可以根据情况选择加或者不加.

<2>try catch代码示例

int[] arr= {1, 2, 3};
try {
    System.out.println("before");
    System.out.println(arr[100]);
    System.out.println("after");
} catch (ArrayIndexOutOfBoundsExceptione) {    // 打印出现异常的调用栈
    e.printStackTrace();
}
System.out.println("after try catch");
// 执行结果
before
java.lang.ArrayIndexOutOfBoundsException: 100
atdemo02.Test.main(Test.java:10)aftertrycatch

一旦 try 中出现异常, 那么 try 代码块中的程序就不会继续执行, 而是交给 catch 中的代码来执行. catch 执行完毕会继续往下执行.

注意:catch可以有多个,也可以再一个catch中捕获多个异常

<3>try catch finally代码示例

int[] arr= {1, 2, 3};
try {
    System.out.println("before");
    arr=null;
    System.out.println(arr[100]);
    System.out.println("after");
} catch (Exceptione) {
    e.printStackTrace();
} finally {
    System.out.println("finally code");}
// 执行结果
before
java.lang.NullPointerException
atdemo02.Test.main(Test.java:12)finallycode

finally 表示最后的善后工作, 例如释放资源

finally是一定执行的代码(即使try中含有return语句)

例如:

publicstaticintfunc() {    try {
        return10;
    } finally {
        return20;
    }
}

// 执行结果20

2.异常的处理流程

1.程序先执行 try 中的代码

2.如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配.

3.如果找到匹配的异常类型, 就会执行 catch 中的代码

4.如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者.

5.无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行).

6.如果上层调用者也没有处理的了异常, 就继续向上传递.

7.一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止.

3.抛出异常(使用throw关键字)

在写代码时,有时候需要手动抛出异常(例如登录界面)示例:

publicstaticintdivide(intx, inty) {
    if (y==0) {
        thrownewArithmeticException("抛出除 0 异常");    }
    returnx/y;
}

三.java异常体系

1.java内置异常

下图表示 Java 内置的异常类之间的继承关系:

1.顶层类 Throwable 派生出两个重要的子类, Error 和 Exception

2.其中 Error 指的是 Java 运行时内部错误和资源耗尽错误. 应用程序不抛出此类异常. 这种内部错误一旦出现,除了告知用户并使程序终止之外, 再无能无力. 这种情况很少出现.

3.Exception 是异常类的父类.

4.其中 Exception 有一个子类称为 RuntimeException , 这里面又派生出很多我们常见的异常类,NullPointerException , IndexOutOfBoundsException 等.

注意:

1Java语言规范将派生于 Error 类或 RuntimeException 类的所有异常称为 非受查异常, 所有的其他异常称为 受查异常.如果一段代码可能抛出 受查异常, 那么必须显式进行处理.

2.自定义异常类

创建一个类,继承内置异常类,实现自定义异常

例如写一个用户登录功能Login:

public static void main(String[] args) {
    try {
        login("admin", "123456");
    } catch (UserError userError) {
        userError.printStackTrace();
    } catch (PasswordError passwordError) {
    passwordError.printStackTrace();
    }
}
public static void login(StringuserName, Stringpassword) throwsUserError,  PasswordError {
    if (!Test.userName.equals(userName)) {
        throw new UserError("用户名错误");
    }
    if (!Test.password.equals(password)) {
        throw new PasswordError("密码错误");
    }
    System.out.println("登陆成功");
}
class UserError extends Exception {
    publicUserError(Stringmessage) {
    super(message);
    }
}
class PasswordError extends Exception {
    public PasswordError(Stringmessage) {
    super(message);
    }
}

注意:

1.自定义异常通常会继承自 Exception 或者 RuntimeException

2.继承自 Exception 的异常默认是受查异常

3.继承自 RuntimeException 的异常默认是非受查异常.

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Java异常处理深入理解

    目录 图片解析: 异常的处理: 处理机制一:try-catch-finally finally的再说明: 处理机制二:throws + 异常类型 开发中应该如何选择两种处理方式? 如何自定义异常类? throw和throws的区别: 总结 图片解析: 1.生成字节码文件的过程可能产生编译时异常(checked),由字节码文件到在内存中加载.运行类此过程可能产生运行时异常(unchecked), 2.JAVA程序在执行过程中所发生的异常事件可分为两类: > Error: Java虚拟机无法解决的的

  • Java:详解Java中的异常

    目录 Java异常 常见异常 throw和throws的区别 final.finally.finalize的区别 总结 Java异常 Java中的异常:又称例外,是一个在程序执行期间发生的事件,它中断正在执行程序的正常指令流 异常的分类:Throwable:类是java语言中所有错误或异常的超类,这意味着只要指示错误或异常,那么肯定是thrawble子类的实例,但是事实上由于错误异常内容过于庞大,所以设计人员将它们分开来,这就是thrawble的两个子类,Error和Exception Erro

  • 全面了解java中的异常处理

    目录 Java 异常处理 1. 什么是异常 2. Java 异常类架构 2.1 Throwable 类 2.2 Error 类 2.3 Exception 类 3. 如何进行异常处理 4. 抛出异常 4.1 实例 4.2 throw 4.3 throws 5. 捕获异常 6. 自定义异常 7. 异常链 8. 小结 Java 异常处理 Java 的异常处理是 Java 语言的一大重要特性,也是提高代码健壮性的最强大方法之一.当我们编写了错误的代码时,编译器在编译期间可能会抛出异常,有时候即使编译正

  • Java异常类型及处理

    目录 一.异常定义 二.异常的结构和分类 三.异常的处理和捕获 四.自定义异常 五.异常的应用 1.打印堆栈 2.弹出流程 六.注意点 总结 一.异常定义 异常就是"意外.例外"的意思,也就是非正常情况.异常本质上是程序上的错误,包括程序逻辑错误和系统错误.异常的处理基本上就是用来兜底的,也是程序开发中程序不愿意看到的.异常最基本的信息就是线程的堆栈信息. 二.异常的结构和分类 Throwable主要分为Error和Exception. 错误:Error类以及他的子类的实例,代表了JV

  • 全面了解java异常

    目录 异常的概念 异常体系 异常的分类 异常产生的过程分析 异常的处理 抛出异常throw 声明异常throws 捕获异常try-catch 捕获异常语法 如何获取异常信息: finally代码块 try catch 语句中有return 的各类情况 异常注意事项 自定义异常 概述 自定义异常演示 异常的概念 异常,在程序中的意思是:程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止. Java的异常机制主要依赖于try.catch.finally.throw和throws五个关

  • Java面向对象之什么是异常

    基础概念 (1)异常:Java程序在运行时期发生的不正常情况. Java就按照面向对象的思想对不正常情况进行描述和对象的封装. (2)异常问题分类: (Throwable:定义对于问题共性的功能.) 1.Error:由系统底层发生的,jvn告诉使用者.不做针对性处理,直接修改代码. 2.Exception:发生并告诉使用者,可以进行针对性的处理. (3)异常的处理情况: 1.遇到问题不进行具体的处理,继续抛给调用者.就是在函数上通过throws关键字声明异常.目的是让调用者可以进行处理. 2.针

  • 一篇文章带你深入了解Java异常

    目录 一.初识异常 1.常见的异常类型 <1>除以0 <2>数组下标越界 <3>访问null对象 2.防御式编程 <1>LBYL <2>EAFP 二.异常的基本用法 1.捕获异常 <1>基本语法: <2>try catch代码示例 <3>try catch finally代码示例 2.异常的处理流程 3.抛出异常(使用throw关键字) 三.java异常体系 1.java内置异常 2.自定义异常类 总结 一.初

  • 一篇文章带你搞懂Java线程池实现原理

    目录 1. 为什么要使用线程池 2. 线程池的使用 3. 线程池核心参数 4. 线程池工作原理 5. 线程池源码剖析 5.1 线程池的属性 5.2 线程池状态 5.3 execute源码 5.4 worker源码 5.5 runWorker源码 1. 为什么要使用线程池 使用线程池通常由以下两个原因: 频繁创建销毁线程需要消耗系统资源,使用线程池可以复用线程. 使用线程池可以更容易管理线程,线程池可以动态管理线程个数.具有阻塞队列.定时周期执行任务.环境隔离等. 2. 线程池的使用 /** *

  • 一篇文章带你搞定JAVA反射

    目录 1.反射的概念 1.概念 2.获取字节码文件对象的方式 2.1 元数据的概念 2.2 获取class对象的方式 1.访问权限 2.获取方法 2.1 访问静态方法 2.2 访问类方法 3.获取字段,读取字段的值 4.获取实现的接口 5.获取构造函数,创建实例 6.获取继承的父类 7.获取注解 4.反射实例 5.总结 1.反射的概念 1.概念 反射,指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对任意一个对象,都能调用它的任意一个方法.这种动态获取信息,以及动态调用对象方法

  • 一篇文章带你深入了解Java基础

    目录 1.String类 1.1两种对象实例化方式 1.2字符串比较 1.3字符串常量是String的匿名对象 1.4String两种实例化方式区别 1.分析直接赋值方式 2.构造方法赋值 1.5字符串常量不可改变 1.6开发中String必用 1.7字符串和字符数组 1.9字符串比较 1.11字符串的替换 1.12字符串的拆分 1.12字符串的截取 1.13其他操作方法 2.1. 给定一个email地址,要求验证其是否正确,提示:可以简单的验证一下,重点验证"@"和".&q

  • 一篇文章带你深入了解Java基础(3)

    目录 1.方法的基本定义 2.方法重载 3.方法的递归调用 4.面向对象的前身是面向过程 5.类与对象 总结 1.方法的基本定义 限制条件:本次所讲解的方法指的是在主类中定义,并且由主方法由主方法直接调用. 方法是指就是一段可以被重复调用的代码块. 在java里面如果想要进行方法的定义,则可以使用如下的方法进行完成. public static 方法返回值 方法名称([参数类型 变量,....]){ 方法体代码 ; return [返回值]; } 在定义方法的时候对于方法的返回值由以下两类:vo

  • 一篇文章带你深入了解Java线程池

    目录 线程池模型 常用线程池 ThreadPoolExecutor 构造函数参数说明 线程池默认工作行为 ForkJoinPool FutureTask 线程数量分析 CPU密集型 IO密集型 总结 线程池模型 一般的池化模型会有两个方法,用于获取资源和释放资源,就像这样: public interface XXPool{ XX acquire(); void release(); } 但是,工程中的线程池一般是生产者和消费者模型,线程池是消费者,任务的提交者是生产者,下面是一个简化的线程池模型

  • 一篇文章带你深入了解Java基础(4)

    目录 1.private实现封装处理 2.构造方法与匿名对象 3.简单java类 4.数组 总结 1.private实现封装处理 如果像想要知道封装,首先必须清楚如果没有封装会怎么样? 没有封装方法中的属性,在所有方法被调用后都可以进行无权限的访问.而当进行了封装操作之后,在实例化对象访问该方法的时候会出现无法访问的问题. TestDemo1.java:11: 错误: name 在 Person 中是 private 访问控制 per.name = "张三"; ^ TestDemo1.

  • 一篇文章带你搞定JAVA内存泄漏

    目录 1.什么是内存泄漏 2.内存泄漏的原因 3.内存泄漏有哪些情况 3.1 代码中没有及时释放,导致内存无法回收. 3.2 资源未关闭造成的内存泄漏 3.3 全局缓存持有的对象不使用的时候没有及时移除,导致一直在内存中无法移除 3.4 静态集合类 3.5 堆外内存无法回收 4.内存泄漏的解决办法 5.内存问题排查 第一步 首先确认逻辑问题 第二步:分析gc是否正常执行 第三步 确认下版本新增代码的改动,尽快从代码上找出问题. 第四步:开启各种命令行和 导出 dump 各种工具分析 总结: 1.

  • 一篇文章带你搞定JAVA泛型

    目录 1.泛型的概念 2.泛型的使用 3.泛型原理,泛型擦除 3.1 IDEA 查看字节码 3.2 泛型擦除原理 4.?和 T 的区别 5.super extends 6.注意点 1.静态方法无法访问类的泛型 2.创建之后无法修改类型 3.类型判断问题 4.创建类型实例 7.总结 1.泛型的概念 泛型的作用就是把类型参数化,也就是我们常说的类型参数 平时我们接触的普通方法的参数,比如public void fun(String s):参数的类型是String,是固定的 现在泛型的作用就是再将St

  • 一篇文章带你搞定JAVA注解

    目录 1.注解是什么 2.jdk支持的注解有哪些 2.1 三种常用的注解: 2.2 元注解 3.注解实例 1.自定义注解 2.在对应的方法上增加注解 3.在项目启动的时候检查注解的枚举 4.总结 1.注解是什么 Java 注解用于为 Java 代码提供元数据,看完这句话也许你还是一脸懵逼,用人话说就是注解不直接影响你的代码执行,仅提供信息.接下我将从注解的定义.元注解.注解属性.自定义注解.注解解析JDK 提供的注解这几个方面再次了解注解(Annotation) 2.jdk支持的注解有哪些 2.

随机推荐