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会有一些风险,比如: 文件是 ...
随机推荐
- kafka的auto.offset.reset详解与测试
1. 取值及定义 auto.offset.reset有以下三个可选值: latest (默认) earliest none 三者均有共同定义: 对于同一个消费者组,若已有提交的offset,则从提交的 ...
- 微信小程序-全局配置、组件、页面跳转、用户信息等
全局配置 三个页面 app.json pages字段 "pages":[ "pages/index/index", # 首页 "pages/home/ ...
- Kubernetes(K8S)是什么?
概述 Kubernetes,又称为 k8s(首字母为 k.首字母与尾字母之间有 8 个字符.尾字母为 s,所以简称 k8s)或者简称为 "kube" ,是一种可自动实施 Linux ...
- Vmware部署Linux无人值守安装Centos7系统
Linux - 无人值守安装服务 # 需求分析 - 使用光盘镜像来安装 Linux 系统的方式; 坦白讲, 该方法适用于只安装少量 Linux 系统的情况, 如果生产环境中有数百台服务器都需安装系统, ...
- Elasticsearch删除操作详解
文章转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247484022&idx=1&sn=7a4de21 ...
- Windows 下JDK绿色免安装制作教程
java自从被oracle收购后,windows下新的版本只有安装版.没有zip免安装. windows安装版有一下坏处 会写注册表 会将java.exe,javaw.exe 等解压到C:\Windo ...
- Tubian系统无法打开Android子系统的解决方法
打开Konsole,Konsole在程序菜单(左下角Logo)-系统中 输入: sudo nano /var/lib/waydroid/waydroid.cfg 回车 按方向键,把光标移动到[prop ...
- P7114 [NOIP2020] 字符串匹配 (字符串hash+树状数组)
好多题解用的扩展KMP(没学过,所以不用这种方法). 我们按照题目要求记F(s)表示s串的权值,可以预处理出前缀权值(用于A)和后缀权值(用于C),枚举AB的长度i=2~n-1,不需要分开枚举,我们只 ...
- 洛谷P1962 斐波那契数列 (矩阵快速幂)
学了矩阵,练一下手... 1 #include<bits/stdc++.h> 2 typedef long long ll; 3 const ll mod=1e9+7; 4 using n ...
- Go_Channel详解
一 channel介绍 单纯地将函数并发执行是没有意义的.函数与函数间需要交换数据才能体现并发执行函数的意义. 虽然可以使用共享内存进行数据交换,但是共享内存在不同的goroutine中容易发生竞态问 ...