Day27:异常详解
异常
1.1 异常概述
异常(Exception)指程序运行中出现的不正常情况:文件找不到、网络异常、非法参数等等。
我们通过代码来了解一下:
public class Demo{
public static void main(String[] args){
int[] a={1,2,3};
method(a);
}
public static void method(int[] a){
Sytem.out.println(a[3]);
}
}
//输出结果
ArrayIndexOutOfBoundsException//数组下标越界
上面我们得到异常中一个非常常见的异常:数组下标越界异常。
1.1.1 异常体系

Exception也是一个类,throwable是所有异常的超类;throwable还有一个子类是错误Error。
Error:表示很严重的问题,无需处理。
Exception:称为异常类,表示程序本身可以处理的问题。
- RuntimeException:在编译期是不检查的,出现问题后需要我们会来修改代码;(也就是说我们在写代码的过程中程序是不会报错的)
- 非RuntimeException:在编译期就必须处理的问题,如果不处理,将不能通过编译,程序更加不会运行;(也就是写代码爆红的时候)
1.2 JVM的默认处理方案
当我们的程序出现异常的时候,如果我们不去处理,Java中的虚拟机会执行默认处理方案。
public class demo{
public static void main(String[] args){
int[] a={1,2,3};
System.out.println("开始");
method(a);
System.out.println("结束");
}
public static void method(int[] a){
System.out.println(a[3]);
}
}
//输出结果
开始
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3//异常出现的类型
at com.liuwei.oop.exception.demo.method(demo.java:11) //异常出现的位置
at com.liuwei.oop.exception.demo.main(demo.java:7)
//结束这个输出语句并没有执行
如果我们不处理异常,交给系统去处理会得到异常的原因、异常的位置输出在控制台,且终止程序运行!
1.3 异常处理
我们为什么需要处理异常呢?
因为交给Java默认处理的话,会终止我们的程序运行!如果我们自己将异常处理了,可以让程序保持运行。
处理异常的方案:
- try—catch—
- throw
1.3.1 try—catch—
格式:
try{
可能出现异常的代码;
}catch(异常的类型 变量名){
如与catch中的异常类型匹配成功后需要执行的异常处理代码;
}
执行流程:
程序执行try内部的代码,判断是否有异常,
若出现异常则将异常实例化
将异常的类型与catch中的异常类型进行匹配
匹配成功后,执行异常处理代码
程序执行后续代码.....
我们去代码中学习一下try—catch—的使用:
public class Demo{
public static void main(String[] args){
int[] a={1,2,3};
System.out.println("开始");
try{
method(a);//需要检查异常的代码
//有异常是会实例化异常并与catch中的异常类型进行匹配,匹配成功执行异常处理代码
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("数组下标访问错误");//异常的处理代码
}
System.out.println("结束");
}
public static void method(int[] a){
System.out.println(a[3]);
}
}
//输出结果
开始
数组下标访问错误
结束
通过上面的代码运行,我们看到我们捕获异常且处理后,后续的代码依然被执行了;
这也就是我们处理异常的初衷:出现异常后不影响后面代码的执行。
但是有需要我们注意的地方是异常处理代码一般来说不是输出一句话,而是要显示异常原因及位置的信息;
我们在捕获异常时实例化了对象,我们可以在异常处理代码的地方调用异常的一些方法来显示我们想要的异常原因及位置的信息。
public class Demo{
public static void main(String[] args){
int[] a={1,2,3};
System.out.println("开始");
try{
method(a);
}catch(ArrayIndexOutOfBoundsException e){
// System.out.println("数组下标访问错误");//异常的处理代码
e.printStackTrace();//我们调用了异常的方法,将错误信息打印出来
}
System.out.println("结束");
}
public static void method(int[] a){
System.out.println(a[3]);
}
}
//输出结果
开始
结束
java.lang.ArrayIndexOutOfBoundsException: 3
at com.liuwei.oop.exception.demo.method(demo.java:16)
at com.liuwei.oop.exception.demo.main(demo.java:8)
我们发现我们的异常处理得到的跟Java异常默认处理方案是一样的,但是仅仅是显示的内容一样,而我们的程序并没有终止。
1.4 Throwable的成员方法
| 成员方法 | 说明 |
|---|---|
| public String getMessage() | 返回此throwable的详细消息字符串 |
| public String toString() | 返回此可抛出的简短描述 |
| public void printStackTrace() | 把异常的错误信息输出在控制台 |
我们在代码里对三种方法进行了解:
- public String getMessage()
public class Demo{
public static void main(String[] args){
int[] a={1,2,3};
System.out.println("开始");
try{
method(a);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println(e.getMessage());
}
System.out.println("结束");
}
public static void method(int[] a){
System.out.println(a[3]);
}
}
//输出结果
开始
3//getMessage();会返回出现异常的原因
结束
我们打开getMessage()的源代码:

发现getMessage();是Throwable类的一个方法;且getMessage();中返回了一个detailMessage

detailMessage是Throwable类的一个成员变量
也就是说我们调用getMessage();时返回给我们的是detailMessage,而detailMessage是Throwable类的属性,也就意味着detailMessage在Throwable类的有参构造中被赋值了,而这个值正是其子类自身调用构造器时传来的;
当try捕捉到异常时会创建该异常的对象,此时该异常类会调用有参构造器,且调用其父类的有参构造器,其父类再去调用父类,最终调到Throwable类的有参构造器对detailMessage进行赋值,最后我们调用getMessage();并返回detailMessage的值。

//简化描述下Throwable有参的构造和getMessage()方法的调用
public class Throwable{
private String detailMessage;
public Throwable(String message){//当异常类的有参构造调动牵动了Throwable的有参构造器的调用,且将 detailMessage初始化了
detailMessage=message;
}
public String getMessage(){
return detailMessage;
}
}
- public String toString()
public class Demo{
public static void main(String[] args){
int[] a={1,2,3};
System.out.println("开始");
try{
method(a);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println(e.toString());
}
System.out.println("结束");
}
public static void method(int[] a){
System.out.println(a[3]);
}
}
//输出结果
开始
java.lang.ArrayIndexOutOfBoundsException: 3//输出了异常类型以及原因;包含了getMessage();的内容
结束
- public void printStackTrace()
public class Demo{
public static void main(String[] args){
int[] a={1,2,3};
System.out.println("开始");
try{
method(a);
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}
System.out.println("结束");
}
public static void method(int[] a){
System.out.println(a[3]);
}
}
//输出结果
开始
结束
java.lang.ArrayIndexOutOfBoundsException: 3
at com.liuwei.oop.exception.demo.method(demo.java:16)
at com.liuwei.oop.exception.demo.main(demo.java:8)
//输出了异常的原因,类型,位置
//printStackTrace();输出的信息是最全的,一般我们使用这个
1.5 编译时异常和运行时异常的区别
Java中的异常有两大类:编译时异常和运行时异常;也被称为受检异常和非受检异常;
所有的RuntimeException及其子类都被成为运行时异常,除外其他的异常都为编译时异常
- 编译时异常:必须显示处理,否则程序会发生错误,编译无法通过;
- 运行时异常:无需显示处理,需要我们修改代码;也可以和编译时异常 一样处理
public class Demo{
public static void main(String[] args){
int[] a={1,2,3};
method(a);//ArrayIndexOutOfBoundsException,需要我们修改代码
}
public static void method(int[] a){
System.out.println(a[3]);
}
}
类似我们上面的代码在编译时没有报错,而运行时报错,就是运行时异常。
编译时异常怎么处理?
也就是我们前面讲的try catch
1.6 异常处理之throws
我们前面已经知道了try catch方式来处理异常,但是并不是所有的异常情况我们都有权限通过try catch方式来处理;
Java提供了另外一种处理方式:throws处理方案
格式:
throw 异常类名;
需要注意的是throws 异常类名;是跟在方法声明的括号之后的!
throws 异常类名仅仅是抛给了调用者,并没有解决异常,如果要解决还得用try catch
//运行时异常的throws处理
public class Demo{
public static void main(String[] args){
//method();//此时throws将异常抛到此处,我们异常并没有解决,我们还是需要处理异常,即用try catch方式来处理
try{
method();
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}
}
public static void method1() throws ArrayIndexOutOfBoundsException{//throws仅仅是向调用者抛出异常,并不能解决异常
int[] a={1,2,3};//我们是可以通过try catch来处理的,这里演示throws处理
System.out.println(a[3]);
}
}
总结:
- 编译时异常必须进行处理:两种处理方案:try catch 和 throws, throws要注意谁调用谁就要处理异常
- 运行时异常可以不处理:我们始终要回来修改代码
Day27:异常详解的更多相关文章
- JAVA基础——异常详解
JAVA异常与异常处理详解 一.异常简介 什么是异常? 异常就是有异于常态,和正常情况不一样,有错误出错.在java中,阻止当前方法或作用域的情况,称之为异常. java中异常的体系是怎么样的呢? 1 ...
- java基础(十五)----- Java 最全异常详解 ——Java高级开发必须懂的
本文将详解java中的异常和异常处理机制 异常简介 什么是异常? 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常. Java异常的分类和类结构图 1.Java中的所 ...
- Java面向对象之异常详解
目录 Java面向对象之异常[一] Java面向对象之异常[二] 捕获异常的规则 访问异常信息 异常对方法重写的影响 finally详解 Java面向对象之异常[一] Java面向对象之异常[二] 往 ...
- cpp异常详解
1. 异常介绍 在函数在执行过程中如果碰到对错误的处理可以有两种方式, 1. 返回错误,2. 使用异常. 如果作为函数的调用者想要知道具体的错误信息, 就需要维护一套错误列表, 或者用string类型 ...
- Java基础 - 异常详解
异常的层次结构 Throwable Throwable 是 Java 语言中所有错误与异常的超类. Throwable 包含两个子类:Error(错误)和 Exception(异常),它们通常用于指示 ...
- java笔记--异常详解与处理
一.异常概念 Throwable类是Java中所有错误或异常的超类. 1.只有当对象是此类(或其子类)的实例时,才能通过Java虚拟机或着Java throw语句抛出. 2.只有此类或其子类才 ...
- c++异常详解
一.什么是异常处理 一句话:异常处理就是处理程序中的错误. 二.为什么需要异常处理,以及异常处理的基本思想 C++之父Bjarne Stroustrup在<The C++ Programming ...
- Java中的异常详解
一.异常定义 阻止当前方法或作用域继续执行的问题,称为异常 二.异常分析 所有不正常类都继承Throwable类,这个类主要有两个子类Error类和Exception类.Error指系统错误 ...
- java异常详解
java异常需要弄清楚如下几个问题: 1.java异常的层次结构 2.搞清楚问题:java中异常抛出后代码还会继续执行吗? 答:该问题可以参考该博文,完美的回答了我的疑惑:http://www.cnb ...
- Android 开发 关于7.0 FileUriExposedException异常 详解
异常原因 Android不再允许在app中把file://Uri暴露给其他app,包括但不局限于通过Intent或ClipData 等方法.原因在于使用file://Uri会有一些风险,比如: 文件是 ...
随机推荐
- k8s日志架构和基本日志
如果一个容器崩溃了.一个Pod被驱逐了.或者一个节点停机了,您通常仍然需要访问您应用程序的日志.为此,您需要一个生命周期与节点.Pod.容器相对独立的存储空间来存储应用程序日志和系统日志. 此时,我们 ...
- 使用Prometheus和Grafana监控nacos集群
官方文档:https://nacos.io/zh-cn/docs/monitor-guide.html 按照部署文档搭建好Nacos集群 配置application.properties文件,暴露me ...
- Elasticsearch:Elasticsearch HQ 介绍
- 通用 HTTP 签名组件的另类实现
1.初衷 开发中经常需要做一些接口的签名生成和校验工作,最开始的时候都是每个接口去按照约定单独实现,久而久之就变的非常难维护,因此就琢磨怎么能够写了一个比较通用的签名生成工具. 2.思路 采用链式调用 ...
- Java并发编程 | 从进程、线程到并发问题实例解决
计划写几篇文章讲述下Java并发编程,帮助一些初学者成体系的理解并发编程并实际使用,而不只是碎片化的了解一些Synchronized.ReentrantLock等技术点.在讲述的过程中,也想融入一些相 ...
- 洛谷P1438 无聊的数列 (线段树+差分)
变了个花样,在l~r区间加上一个等差数列,等差数列的显著特点就是公差d,我们容易想到用线段树维护差分数组,在l位置加上k,在l+1~r位置加上d,最后在r+1位置减去k+(l-r)*d,这样就是在差分 ...
- windows下利用_popen,_wpoen创建管道进行系统命令输出数据
转载: https://blog.csdn.net/greless/article/details/72383762 参考: http://www.linuxidc.com/Linux/2011-04 ...
- JVM中的堆
堆 内存结构 堆的核心概念 <java虚拟机规范>中对java堆的描述是:所有的对象实例以及数组都应当在运行时分配在堆上. 一个JVM实例只存在一个堆内存(就是new 出来一个对象),ja ...
- 任务清单小功能的实现(任务的增、删、改、查、存储)使用Vue实现
文章目录 1.实现的效果(视频演示) 2.重点讲解(编辑的实现) 2.1 提示(官网介绍nextTick的用法) 3.编辑功能的核心代码 4.完整的代码 5.以往练习 任务清单案例(纯Vue) 实现的 ...
- golang中的一些实用功能
0.1.索引 https://waterflow.link/articles/1663921524839 通过使用一些通用代码来节省时间,而无需单独实现它们.以下是一些开发中经常会用到的函数实现的列表 ...