目录
1.体系结构
error:错误,因硬件问题无法解决的。
Exception:异常类,可以进行处理的
RuntimeException及其子类:称运行时异常,程序运行时发生的报错
除了 “RuntimeException及其子类”之外的异常:称编译时异常,必须先处理,否则程序不能编译运行。显示红色波浪线
编译时异常和运行时异常的区别
-
编译时异常
-
都是Exception类及其子类
-
必须显示(主动)处理,否则程序就会发生错误,无法通过编译,显示红色波浪线无法进行编译
-
-
运行时异常
-
都是RuntimeException类及其子类
-
无需显示处理,也可以和编译时异常一样处理
-
//思考:控制台为什么会有这样的红色字体呢? 是谁打印的?
int [] arr = {1,2,3,4,5};
System.out.println(arr[10]);//当代码出现了异常,那么就在这里创建了一个异常对象.
//new ArrayIndexOutOfBoundsException();
//首先会看,程序中有没有自己处理异常的代码.
//如果没有,交给本方法的调用者处理.
//最终这个异常会交给虚拟机默认处理.
//JVM默认处理异常做了哪几件事情:
//1,将异常信息以红色字体展示在控制台上.
//2,停止程序运行. --- 哪里出现了异常,那么程序就在哪里停止,下面的代码不执行了.
System.out.println("嘿嘿嘿,我最帅");//此输出语句不在执行
JVM默认处理异常的方式
-
如果程序出现了问题,我们没有做任何处理,最终JVM 会做默认的处理,处理方式有如下两个步骤:
-
把异常的名称,错误原因及异常出现的位置等信息输出在了控制台
-
程序停止执行
-
2.异常处理的方式
2.1自己不处理,交给调用者处理
(1) throws 方式处理异常
定义格式
public void 方法() throws 异常类名 {
}
注意:这个格式是写在方法的定义处,标识声明一个异常。【主动标明一个异常】
无论编译时异常还是运行时异常,如果方法的调用者未对其处理,最终交给虚拟机JVM处理报错。程序停下来,后面的代码不再执行
注意事项
-
这个throws格式是跟在方法的括号后面的
-
编译时异常必须要进行处理,两种处理方案:try...catch …或者 throws。如果采用 throws 这种方案,在方法上进行显示声明,将来谁调用这个方法谁处理,如果都没处理就交给JVM处理,进行报错
-
运行时异常因为在运行时才会发生,所以在方法后面可以不写,运行时出现异常默认交给jvm处理
(2) throw抛出异常
思考∶
以前出现了异常,虚拟机帮我们创建一个异常对象,抛给调用者。但是如果我们需要自己手动创建一个异常对象该如何写?
-
格式
throw new 异常();
或:
throw new xxxException("异常产生的原因");
注意: 1.throw关键字必须写在方法的内部 2.throw关键字【后边】【new的对象】【必须是】Exception或者Exception的子类对象 3.throw关键字抛出指定的异常对象,我们就必须处理这个异常对象 throw关键字后边创建的是【RuntimeException】或者是【 RuntimeException】的【子类对象】,我们可以不处理,默认交给JVM处理(打印异常对象,中断程序) throw关键字后边创建的是【编译异常】(写代码的时候报错),【程序根本无法进行编译运行】我们就必须处理这个异常,要么【throws】,要么【try...catch】
-
注意
这个格式是在方法内的,表示当前代码手动抛出一个异常,下面的代码不用再执行了
public static void main(String[] args) { System.out.println("家里有一个貌美如花的老婆"); System.out.println("还有一个当官的兄弟"); System.out.println("自己还有一个买卖"); System.out.println("这样的生活你要不要?"); throw new RuntimeException(); //当代码执行到这里,就创建一个异常对象 //该异常创建之后,暂时没有手动处理.抛给了调用者处理 //下面的代码不会再执行了. //System.out.println("武大郎的标准生活"); }
-
throws和throw的区别
throws throw 用在方法声明后面,跟的是异常类名 用在方法体内,跟的是异常对象名 表示声明异常,调用该方法有可能会出现这样的异常 表示手动抛出异常对象,由方法体内的语句处理
public class ExceptionDemo8 {
public static void main(String[] args) {
//int [] arr = {1,2,3,4,5};
int [] arr = null;
printArr(arr);//就会 接收到一个异常.
//这个方法没有处理方式,最终交给虚拟机处理
}
private static void printArr(int[] arr) {
if(arr == null){
//调用者知道成功打印了吗?
//System.out.println("参数不能为null");
throw new NullPointerException(); //当参数为null的时候
//手动创建了一个异常对象,抛给了调用者,产生了一个异常
}else{
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
}
最终会报错:
2.2 自己处理的方式
(1)try-catch方式处理异常
-
定义格式
try { 可能出现异常的代码; } catch(异常类名 变量名) { 异常的处理代码; }
-
执行流程
-
程序从 try 里面的代码开始执行
-
出现异常,就会跳转到对应的 catch 里面去执行
-
执行完毕之后,程序还可以继续往下执行
-
//好处:为了能让代码继续往下运行.
int [] arr = null;
try{
//有肯能发现异常的代码
printArr(arr);
}catch (NullPointerException e){
//如果出现了这样的异常,那么我们进行的操作
System.out.println("参数不能为null");
}
System.out.println("嘿嘿嘿,我最帅!!!");
}
private static void printArr(int[] arr) {
if(arr == null){
throw new NullPointerException();
}else{
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
执行结果:
好处:可以让程序继续往下执行
注意
-
如果 try 中没有遇到问题,怎么执行?
会把try中所有的代码全部执行完毕,不会执行catch里面的代码
-
如果 try 中遇到了问题,那么 try 下面的代码还会执行吗?
那么直接跳转到对应的catch语句中,try下面的代码就不会再执行了 当catch里面的语句全部执行完毕,表示整个体系全部执行完全,继续执行下面的代码
-
如果出现的问题没有被捕获,那么程序如何运行?
那么try...catch就相当于没有写.那么也就是自己没有处理. 默认交给虚拟机处理.
-
同时有可能出现多个异常怎么处理?
出现多个异常,那么就写多个catch就可以了. 注意点:如果多个异常之间存在子父类关系.那么父类一定要写在下面【多个catch的最后一个】
Throwable成员方法
-
常用方法
方法名 说明 public String getMessage() 返回此 throwable 的详细消息字符串 public String toString() 返回此可抛出的简短描述 public void printStackTrace()【常用】 把异常的错误信息输出在控制台
//public String getMessage() 返回此 throwable 的详细消息字符串
//public String toString() 返回此可抛出的简短描述
//public void printStackTrace() 把异常的错误信息输出在控制台(字体为红色的)
try {
int [] arr = {1,2,3,4,5};
System.out.println(arr[10]);
/*
虚拟机帮我们创建了一个异常对象
new ArrayIndexOutOfBoundsException();
再把此对象传递给Catch中的参数【e】,则e可以调用 throwable方法
*/
} catch (ArrayIndexOutOfBoundsException e) {
/*String message = e.getMessage();
System.out.println(message);*/
/* String s = e.toString();
System.out.println(s);*/
e.printStackTrace();
}
System.out.println("嘿嘿嘿");
自定义异常
实现步骤
1. 定义异常类
2. 写继承关系
3. 提供空参构造
4. 提供带参构造
自定义异常类:
java提供的异常类,不够我们使用,需要自己定义一些异常类
格式:
public class XXXExcepiton extends Exception | RuntimeException{
添加一个空参数的构造方法
添加一个带异常信息的构造方法
}
注意:
1.自定义异常类一般都是以Exception结尾,说明该类是一个异常类
2.自定义异常类,必须的继承Exception或者RuntimeException
继承Exception:那么自定义的异常类就是一个编译期异常,如果方法内部抛出了编译期异常,就必须处理这个异常,要么throws,要么try...catch
继承RuntimeException:那么自定义的异常类就是一个运行期异常,无需处理,交给虚拟机处理(中断处理)
*/
public class RegisterException extends /*Exception*/ RuntimeException{
//添加一个空参数的构造方法
public RegisterException(){
super();//默认调用的父类的空参构造方法
}
/*
添加一个带异常信息的构造方法
查看源码发现,所有的异常类都会有一个带异常信息的构造方法,方法内部会调用父类带异常信息的构造方法,让父类来处理这个异常信息
*/
public RegisterException(String message) {
super(message);
}
}