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-ingress配置websocket支持
具体来说,使用的ingress-controller不一样,有关的设置也不太一样 Kubernetes Ingress Controller (k8s官方) 参考 http://github.com/ ...
- Elastic:使用Postman来访问需要账号密码的Elastic Stack
- openresty(nginx) 配置 stream 转发
nginx从1.9.0开始,新增加了一个stream模块,用来实现四层协议的转发.代理或者负载均衡等. (1)关于stream域的模块有哪些? 目前官网上列出的第三方模块.简直就是http模块的镜像. ...
- 《Thinking In Java》作者:不要使用并发!
前言 今天纯粹就是带你们来读读书的~ 最近除了工作,特地买回了自己很喜欢的作者新发售的一本书<On Java>,作者是我的老朋友布鲁斯·埃克尔,在Java领域很有名,你可能没听过他的名字, ...
- POJ2763 Housewife Wind (树链剖分)
差不多是模板题,不过要注意将边权转化为点权,将边的权值赋给它所连的深度较大的点. 这样操作过后,注意查询ask()的代码有所改变(见代码注释) 1 #include<cstdio> 2 # ...
- C语言中的位域的使用
转载:http://blog.sina.com.cn/s/blog_648d306d0100mv1c.html C语言中的位域的使用一.位域 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几 ...
- Nebula Graph介绍和SpringBoot环境连接和查询
Nebula Graph介绍和SpringBoot环境连接和查询 转载请注明来源 https://www.cnblogs.com/milton/p/16784098.html 说明 当前Nebula ...
- Containerd-1.6.5 镜像容器操作
一.Containerd 镜像操作 1 基本参数 [root@ecs-65685 ~]# ctr c NAME: ctr containers - manage containers USAGE: c ...
- CRT & EXCRT 学习笔记
这玩意解决的是把同余方程组合并的问题. CRT的核心思想和拉格朗日插值差不多,就是构造一组\(R_i\)使得$\forall i,j(i \neq j) $ \[R_im_i = 1, R_im_j ...
- Linux安装oracle 12C
安装虚拟系统CentOS6.5,分配给至少1G的内存,其他条件适当高些,具体参考官方文档 环境准备 vim /etc/profileexport JAVA_HOME=/opt/jdk1.7.0_79e ...