一、异常
1.简介
程序在运行时可能出现的不正常的描述,如果程序出现了异常但不进行处理程序会无法编译或者终止。都继承了throwable类
Error类是正常情况下我们无法预料到的,我们无法处理的,是属于JVM级别的错误
Exception类是经过我们捕获可以处理的。分为编译时异常(检查性异常)和运行时异常(非检查行异常)
二、检查性异常(编译时异常)
用idea在写代码的时候,编译器会帮我们进行检查,也就是会爆红
三、非检查性异常(运行时异常)
1. 异常的语法
try{
可能出现异常的代码块
} catch(捕获到的异常类型 变量){ 发生异常后要执行的语句 }
可能出现异常的地方在try后面用{ }包起来,在catch的小括号里面写异常类型也就是捕获异常,catch{ }里写提示,这样程序就会接着向下执行。
2. catch的执行时机:
是在try 的代码块出现了异常后才会执行catch里面的语句
(1)try里没有出现异常,不会执行catch里面的语句
(2)try里出现了异常
3. 如何处理异常呢
(1)可以打印异常信息程序员自己根据信息的提示进行处理
(2)也可以抛给调用者
例如工作人员解决不了的问题,交给工作人员的领导进行处理
4.多种异常的处理
(1)各个异常之间没有继承关系,顺序随意
可以分开写,也可以写在一个catch语句里面 用" | "连接,也可以直接写它们的父类 Exception
public class Exception02 {
public static void main(String[] args) {
try{
int[] nums = new int[5];
nums[5] = 100;
String str = null;
int length = str.length();
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("====数组下标越界异常====");
}catch (NullPointerException e){
System.out.println("====空指针异常====");
}
//简化写在一个catch语句里面
try{
int[] nums = new int[5];
nums[5] = 100;
String str = null;
int length = str.length();
}catch(ArrayIndexOutOfBoundsException|NullPointerException e){
e.printStackTrace();
}
//简化 直接写它们的父类
try{
int[] nums = new int[5];
nums[5] = 100;
String str = null;
int length = str.length();
}catch(Exception e){
e.printStackTrace();
}
}
}
(2)如果有继承关系,那么子类要写在父类的前面
否则会报编译时异常
5.具体案例
5.1 空指针异常 NullPointerException
null是指没有地址 这里区分一下 null 和"" null是没有地址,而""是有地址但是里面的内容是空的
eg: 做饭,null是指没有锅。而""是指有锅但是里面没有米
上图种引用变量s指向的地址是空的,那么怎么会有长度呢。
5.2 数组越界异常 ArrayIndexOutofBoundException
上述代码 数组的下标是 0 - 4,而for循环里面遍历到了5,访问不在数组的下标范围内,所以会报数组越界异常
5.3 类型转换异常
上述代码,儿子类和狗类没有关系,所以会出现错误,
而 f 指向的是儿子类,儿子类继承了父类亲,所以可以向下转型。
四、自定义异常
如果系统提供给我们的异常类型已经不能满足我们的需求了,我们可以自定义异常,也就是继承系统的异常类。
继承Exception的是编译时异常
继承RuntimeException的是运行时异常
public class Exception05 {
public static void main(String[] args) {
try {
Person p = new Person("小明",2220);
}catch (AgeIllegalException e){
e.printStackTrace();
}
System.out.println("年龄不合法 ");
}
}
class Person{
private String name;
private int age;
public Person(String name, int age) throws AgeIllegalException{
this.name = name;
if(age < 1||age > 130){
throw new AgeIllegalException("年龄非法");
}
this.age = age;
}
}
class AgeIllegalException extends Exception {
public AgeIllegalException() {
super();
}
public AgeIllegalException(String message) {
super(message);
}
}
五、finally语句
用在try catch后面作为异常捕获的结尾
如果有catch必须写在catch后,否则会报编译错误
如果有finally一定会执行里面的语句
案例1.
public class Demo1 {
public static int test1(){
int i = 1;
try {
i++;
System.out.println("try block, i = "+i);
} catch (Exception e) {
i--;
System.out.println("catch block i = "+i);
} finally {
i = 10;
System.out.println("finally block i = "+i);
}
return i;
}
public static void main(String[] args){
int result = test1();
System.out.println(result);
}
}
运行结果
解析:没有异常不会执行catch里面的语句
案例2
public class Demo2 {
public static int test2(){
int i = 1;
try {
i++;
throw new Exception();
} catch (Exception e) {
i--;
System.out.println("catch block i = " + i);
} finally {
i = 10;
System.out.println("finally block i = " + i);
}
return i;
}
public static void main(String[] args){
int result = test2();
System.out.println(result);
}
}
运行结果
解析:因为在try里抛出一个异常,所以会捕获异常,catch里的代码块会执行
3。案例3 try代码块里面有return 语句,finally里面没有return语句
public class Demo3 {
public static int test3(){
//try 语句块中有 return 语句时的整体执行顺序
int i = 1;
try{
i++;
System.out.println("try block, i = " + i);
return i;
} catch (Exception e) {
i ++;
System.out.println("catch block i = " + i);
return i;
} finally {
i = 10;
System.out.println("finally block i = " + i);
}
}
public static void main(String[] args){
int result = test3();
System.out.println(result);
}
}
运行结果
解析:try里面有return语句会执行finally 不会执行catch里面的代码
4. try和finally里都有return语句
public class Demo4 {
public static int test4(){
//finally 语句块中有 return 语句
int i = 1;
try {
i++;
System.out.println("try block, i = " + i);
return i;
} catch (Exception e) {
i++;
System.out.println("catch block i = " + i);
return i;
} finally {
i++;
System.out.println("finally block i = " + i);
return i;
}
}
public static void main(String[] args){
int result = test4();
System.out.println(result);
}
}
运行结果
解析:执行完try语句后会执行finally语句,finally代码块里有return语句,则方法结束,不会执行try里的return
六、throw和throws关键字
1.throw
throw 抛出异常
当程序可能存在异常时可以使用thorw关键字抛出异常,是在方法中使用的
2.throws
用来声明可能发生哪些异常,写在方法名后面的
修饰符 返回类型 方法名(参数列表) throws 异常列表 {
// 方法体
}