java语言中将程序执行过程中发生的不正常情况称为异常,语法错误和逻辑错误不是异常
1)Error(错误),java虚拟机无法解决的严重问题,如:jam系统内部错误,资源耗尽
2)Exception:因编译错误或偶然的外在因素导致的一般性问题,可以用针对代码进行处理,如空指针访问等。
异常分为两大类,运行时异常和编译时异常
运行时异常编译器检查不出来,一般是编程逻辑错误,运行时异常可以不做处理,编译时异常是编译器要求必须处置的异常
空指针异常,当程序试图在需要对象的地方使用null,抛出该异常
String name = null;
sout(name.length()); //运行抛出空指针异常
数学运算异常,当出现异常的运算条件时,抛出此异常
int a = 10;
int b = 0;
int c = a/b; //被除数不能为0,抛出数学运算异常
数组下标越界异常,用非法索引访问数组时抛出的异常
int[] arr = {1,2,4};
sout(arr[3]); //索引为3的数组没有元素,抛出数组下标越界异常
类型转换异常,当试图将对象强制转换为不是实例的子类时,抛出该异常
class A{ }
class B extends A{ }
class C extends A{ }
A a = new B();
B b = (B)a;
C c = (C)a;
//实际运行类型为B类,与C类无关,不能转换为C类,抛出类型转换异常
数字格式不正确异常,当程序试图将字符串转换为一种数值类型,但该字符串不能转换为适当格式,抛出该异常
String name = "张三";
int num = Integer.parseInt(name);
//不能将字符串“张三”转换为整数,抛出数字格式不正确异常
java提供try和catch块来处理异常,try包含可能出现错误的代码。catch用于处理块中发生的异常,没有finally语法也可以通过
//语法格式举例,快捷键 Crtl Alt + t
int num1 = 10;
int num2 = 0;
try{
int res = num1/num2;
}catch(Exception e){
sout(e.getMessage());
}
细节
1.如果异常发生了则异常发生后面的代码不会再执行,直接进入catch块
2.如果异常没有发生,则顺序执行try的代码块,不会进入catch
3.如果希望不管是否发生异常,都执行某段代码,则在后面加上finally{}
4.可以有多个catch语句捕获不同的异常,要求父类异常在后,子类异常在前
try{
Person person = new Person();
person = null;
sout(person.name);
int num1 = 10;
int num2 = 0;
int res = num1/num2;
}catch(NullPointerException e){ //捕获空指针异常
sout(e.getMessage());
}catch(ArithMeticException e){ //捕获数学运算异常
sout(e.getMessage());
}catch(Exception e){ //父类异常,捕获全部异常,写在子类异常之后
sout(e.getMessage());
}finally{
sout("hahaha");
}
5.可以进行try-finall配合使用,这种用法相当于没有捕获异常,因此程序会直接崩掉,应用场景就是执行一段代码,不管是否发生异常,都必须执行某个业务逻辑
try{
int num1 = 10;
int num2 = 0;
}finally{
sout(“执行了finally”;) //输出这句话,程序报错终止
}
sout(“程序继续执行”);
如果一个方法可能生成某种异常,但不能确定如何处理,则应显示德声明抛出异常,表示该方法不处理,交给方法的调用者处理
在方法声明中用throws语句可以抛出异常列表,throws后面的异常可以是产生的类型异常,也可以是他的父类
public void f2() throws NullPointerException{
//声明抛出异常
}
public void f2() throws NullPointerException,ClassCastException{
//声明抛出异常列表
}
public void f2() throws Exception{
//声明抛出所有异常
}
对于运行时异常,程序员没有处理,默认就是throws的方式处理
public void f1(){ //在这里默认会有一个throws的异常处理方式
int num = 10
int num1 = 20;
i nt res = num/num1;
}
子类重写父类方法时,所抛出的异常类型要么和父类抛出的异常类型一致,要么为父类抛出异常类型的子类,不能扩大其范围
在throws过程中,如果方法有try-catch,就相当于处理异常,不用再throws
当程序中出现某些错误,但该错误信息并没有在Throwable子类中描述处理,这个时候可以自己设计异常类,用于描述该信息
步骤
自定义异常类名,继承Exception或RunTimeException,一般继承RunTimeException,运行时异常
public class CustomException {
public static void main(String[] args) {
int age = 20;
if (!(age >= 18 && age <= 120)){
throw new AgeException("年龄应该在18-120之间");
}
System.out.println("你的年龄范围正确");
}
}
class AgeException extends RuntimeException{
public AgeException(String message) {
super(message);
}
}