一、异常
异常的基本理解:
1、异常是程序在“编译”或“执行”的过程中可能出现的问题。
2、异常是程序不能实现完整执行流程的一种现象。
异常的原因:
(一)注意:以下的异常类型都继承自RuntimeException或者RuntimeException的子类。而RuntimeException产生的原因一般有两个方面:一方面是程序员业务没有考虑好,另一方面是编程逻辑不严谨。
1、数组索引越界异常:ArrayIndexOutOfBoundsException
public class ExceptionDemo{
public static void main(String[] args){
//数组索引越界异常:ArraIndexOutOfBoundsException
int[] arr = {1,2,3}
System.out.println(arr[2]);
System.out.println(arr[3]);//当代码执行这一行时将出现数组索引越界异常
}
}
2、空指针异常:NullPointerException(空指针直接输出没有问题,但调用空指针的变量的功能就会报错)
public class ExceptionDemo{
public static void main(String[] args){
//空指针异常:NullPointerException
String name = null;//代表没有指向任何字符串
System.out.println(name);此时输出没问题
System.out.println(name.length());//当调用length()时将报错
}
}
3、类型转换异常:ClassCastException
public class ExceptionDemo{
public static void main(String[] args){
//类型转换异常:ClassCastException
Object o = 23;
String s = (String) o;//字符串变量不能指向整型变量
}
}
4、数学操作异常:ArithmeticException
public class ExceptionDemo{
public static void main(String[] args){
//数学操作异常:ArithmeticException
int c = 10 / 0;
}
}
5、数字转换异常:NumberFromatException
public class ExceptionDemo{
public static void main(String[] args){
//数字转换异常:NumberFormatException
String number = 334aaas;
Integer it = Integer.valueOf(number);
System.out.println(it+1);
}
}
(二)此处为编译时异常:
注意:编译时异常的作用是担心程序员编程时考虑不周,在编译阶段就爆出错误,目的在于提醒不要出错!
public calss Exception{
public static void main(String[] args){
String data = "2020-01-12 10:23:21";
//创建一个简单日期格式化类:
SimpleDateFormat sdf = new SimpleDateFormat(pattern:"yyyy-MM-dd HH:mm:ss");
//解析字符串时间成为日期对象
Date d = sdf.parse(date);//此处parse地下会爆出红色波浪线,异常类型为ParseException
System.out.println(d);
}
}
此时可以使用throws抛出异常进行处理,如果不处理编译时不能通过。
public calss Exception{
public static void main(String[] args) throws ParseException{
String data = "2020-01-12 10:23:21";
//创建一个简单日期格式化类:
SimpleDateFormat sdf = new SimpleDateFormat(pattern:"yyyy-MM-dd HH:mm:ss");
//解析字符串时间成为日期对象
Date d = sdf.parse(date);
System.out.println(d);
}
}
异常的分类:
一般把编程中遇到的异常分为运行时异常(所有RuntimeException及其所属子类)和编译时异常(Exception及其直接子类)。
运行时异常:继承自RuntimeException的异常或者继承自RuntimeException子类的异常,在编译阶段不会报错,在运行阶段才会报错。
编译时异常:没有继承:RuntimeException的异常,在编译阶段就会报错。
注意:所有的异常都继承于Throwable,而Throwable又继承于Object。
二、异常的处理机制
处理异常的目的:避免程序中出现异常影响程序运行,同时处理可能出现的异常,让代码更稳健。
1、异常的默认处理流程(默认处理机制并不理想)
1.默认会在出现异常的代码位置创建一个异常对象:例如ArrayIndexOutOfBoundsException.
2.异常会从方法中出现的点抛给调用者,调用者最终抛给JVM。
3.虚拟机接收到异常对象后,先在控制台直接输出异常栈信息数据。
4.直接从当前执行的异常点终止当前程序。
5.后续代码不再执行。
2、编译时异常的处理机制
(一)编译时异常的三种处理方式
1.出现异常时直接抛给调用者,调用者也继续抛出去。
2.出现异常时自己捕获处理。
3.前两者的结合,出现异常直接抛给调用者,调用者捕获处理。
(二)处理方式展示
1.throws:用在方法上,可将方法内部出现的异常抛给方法的调用者去处理。
(注意:这种方式并不友好,发生异常时自己不处理,如果异常最终抛给了JVM将会引起程序死亡。)
2.try...catch...
这种方式叫做监视捕获异常,用在方法内部,可以将方法内部出现的异常直接捕获处理。
由于放生异常的方法时自己独立完成异常处理,程序可以继续往下执行。
try-catch基础格式:
try{
//监视可能出现异常的代码
}catch(异常类型1 变量){
//处理异常
}catch(异常类型2 变量){
//处理异常
}...
异常处理原理:
1.把可能出错的代码放入try代码块中封装为对象。
2.被catch后面的(Exception e)中的异常对象接收。
3.接收后执行catch后面的代码块的代码。
4.try-catch后面的代码正常执行。
注意:
1.try代码块中的代码无异常时,catch中的代码不执行。
2.try代码块中的代码有异常时,catch对其进行捕获,此时try代码块中异常代码后面的代码不再执行。
3.异常处理方式之catch后面的代码形式:
catch代码块中可以什么都不写;
catch代码块中可以自定义提示信息;
打印异常信息,使用e.printStackTrace(),e.toString(),e.getMessage(),throw e
4.什么情况下,try...catch...后面的代码不再执行?
在catch代码块中使用throw抛出异常时;
catch代码块中没有正常的进行异常捕获;
try代码块中有return时;
5.什么情况下,try...catch...后面的代码一定执行?
只要将必须执行的代码放入finally中
6.return和feinally的执行顺序?
先执行finally再执行return;
7.finally的使用场景
关闭数据库资源时;
关闭IO流资源时;
关闭Socket资源时;
8.在try代码块中使用System.exit()终止虚拟机的代码时,finally中的代码将不被执行。
推荐格式:Exception可以捕获一些异常类型
try{
//可能出现异常的代码
}catch(Exception e){
e.printStackTrace();//直接打印异常栈信息
}
#多重Catch的原理
当try中出现异常后,将异常与catch后面的异常类型一次匹配,执行与try中异常类型一致的catch语句,一旦执行其中一条catch后,其他catch将被忽略。在安排catch语句的顺序时,一般将子类异常放在前面,父类异常放在后面。
3.前两者结合案例:先使用throws抛给方法调用者,然后使用try...catch..捕获异常
3、运行时异常处理机制:
1.一般情况下可以不处理,程序会默认抛出RuntimeException.
2.按照原理规则建议处理,处理方式是在最外层使用try...catch...捕获异常即可。
public class Test{
public static void main(String[] args){
System.out.println("程序开始。。。。")
try{
text(a:5, b:0);
}catch(Exception e){
e.printStackTrace();
}
}
System.out.println("程序终止。。。")
}
public static void test(int a, int b){
System.out,println(a);
System.out.println(b);
int c = a / b;
System.out.println(c);
}