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会有一些风险,比如: 文件是 ...
随机推荐
- Linux查看文件内容和压缩文件命令
查看文件内容 一些重要的目录: /usr/share/ 帮助文档.说明文档/var/log/ 日志/var/run/ 运行中程序/var/tmp 临时文件 根 ...
- useContext 解决函数父子组件传值
1在父组件外部定义变量A创建上下文,2在父组件使用变量A<A.Provider> <子组件/> </A.Provider> ,3.在子组件中创建变量使用useCon ...
- SVM公式详尽推导,没有思维跳跃。
假定数据集\(T=\{(x_1,y_1),(x_2,y_2),...,(x_n,y_n)\},x_n \in R_k, y_n \in \{1,-1\}\)线性可分,SVM的优化目标是: 优化一个超平 ...
- 报时机器人的rasa shell执行流程分析
本文以报时机器人为载体,介绍了报时机器人的对话能力范围.配置文件功能和训练和运行命令,重点介绍了rasa shell命令启动后的程序执行过程. 一.报时机器人项目结构 1.对话能力范围 (1)能够 ...
- 一文搞定 Spring事务
Spring 事务 上文 使用SpringJDBC 1.JDBC事务控制 不管你现在使用的是那一种ORM开发框架,只要你的核心是JDBC,那么所有的事务处理都是围绕着JDBC开展的,而JDBC之中 ...
- 分布式存储系统之Ceph集群RadosGW基础使用
前文我们了解了MDS扩展相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16759585.html:今天我们来聊一聊RadosGW的基础使用相关话题: ...
- 后端框架学习-----mybatis(4)
文章目录 4.解决属性名和字段名不一致的问题 4.解决属性名和字段名不一致的问题 1.问题.数据库字段名和属性名不一致,导致查出的数据部分为空 2.resultMap(用于解决数据库表中的字段和属性) ...
- 齐博x1标签实例:调用多个圈子同时调用相关会员
看这一篇之前,请先看上一篇,因为他们有关联性比如要实现这样的效果 可以通过下面的代码可以实现 {qb:tag name="xxx" type="qun" row ...
- DevOps|1024程序员节怎么做?介绍下我的思路
1024,祝每个程序员小哥哥小姐姐节日快乐. 因为在研发效能部门,我支持过几次 1024 程序员节的活动,所以经常有朋友问我1024 程序员节怎么做,本篇就是简单介绍下我的思路,希望对你有用. 102 ...
- 45.限流Throttling及源码解析
什么是限流? 限流类似于权限机制,它也决定是否接受当前请求,用于控制客户端在某段时间内允许向API发出请求的次数,也就是频率 假设有客户端(比如爬虫程序)短时间发起大量请求,超过了服务器能够处理的能力 ...