异常处理
Throwable
Throwable是异常最顶端的类
它的子类:Error(服务器崩溃 数据库崩溃)
Exception(异常类)
Exception中最常见的就是:RuntimeException(运行时异常)
异常的几种类型:
空指针异常:
int[] array = new int[4];
array = null;
System.out.println(array[1]);
运行程序时,会报空指针异常
NullPointerException(空指针)
空指针异常也就是访问了一块不属于我的空间
越界异常:
int[] array = new int[4];
System.out.println(array[5]);
运行时会报,越界异常
ArrayIndexOutOfBoundsException(越界异常)
越界异常就是你打印的这个角标大于这个数组的长度
算术异常
System.out.println(10/0)
运行时,会报算术异常
ArithmeticException
算术异常是一个数除以0,就会报算术异常
出现异常该如何解决?
1.出现异常要去找上级解决
2.找上级解决相当于找 任务的调用者
main函数的调用者 JVM去处理
3.JVM默认的处理方式:
打印异常类 错误信息 和 错误发生的位置
直接停止程序
除了让系统自己处理异常外,我们自己也可以处理异常
使用try...catch...finally 方法
try: 指测试异常代码
catch: 指捕获异常信息
finally指一场结束后 要做的事情
这里我们创建一个测试异常的类
class TestException{
public int fun(int a,int b){
return a / b;
}
}
public class Demo {
public static void main(String[] args) {
TestException test = new TestException();
try{
int num = test.fun(5, 0);
}catch (ArithmeticException e){
System.out.println("你除数 为 0");
}
System.out.println("哈哈");
}
}
程序执行完后打印的结果: 你除数为0
哈哈
为什么"哈哈"也会被打印?
因为catch捕获到了 try中的异常后 程序继续运行
所以"哈哈"也会被打印
如果fun中除数不是0,就会打印 num 和 "哈哈"
try…catch捕获异常的流程
1.函数中 某句代码 发生异常
2.发生异常 就产生了异常对应的 异常对象
3.这个异常对象 返回给调用者
1)调用者没有对异常进行处理
这时就会把异常交给上级,交给JVM去处理
JVM就会使用默认的处理方式
2)调用者进行异常处理(使用try...catch)
这时返回的异常对象会跟catch进行匹配
如果匹配成功就会执行catch中的语句
程序还是会继续运行
多catch处理异常
int[] array = new int[4];
try{
arr = null;
System.out.println(arr[1]);
System.out.println(10 / 0);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("你越界了");
}catch (NullPointerException e) {
System.out.println("你空指针了");
}catch (ArithmeticException e) {
System.out.println("你除以0了");
}catch (Exception e) {
System.out.println("出错了");
}
System.out.println("哈哈");
运行这段代码时发现只打印了 "你空指针了"和"哈哈"
因为在匹配catch的时候 有一个被匹配上了
其他catch就不会被匹配了
当arr = null;
System.out.println(arr[1]);
执行后 出现了空指针异常 catch中匹配到了
catch (NullPointerException e) {
System.out.println("你空指针了");
}
那么其他的就不会被继续匹配了
这里需要注意的是 最后一个catch
catch (Exception e) {
System.out.println("出错了");
}
需要放在最后,因为Exception可以被所有异常匹配到
如果放在最前面,那么后面的catch就没有意义了
系统就会报红
所以catch中 异常要从小到大
小练习
public class Demo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
whilie(true){
System.out.println("输入整数");
String string = scanner.nextLine();
if(string.equals(quit)){
break;
}
try{
int num = Integer.parseInt(string);
list.add(num);
} catch(Exception e){
System.out.println("输入错误,请重新输入");
}
}
System.out.println(list);
}
}
finally
final finally finalize 的 区别
final:
类 不能被继承
方法 不能被重写
变量 变量变常量
finally 异常处理时使用的
finalize() 是一个方法 是坐垃圾回收的时候用的 是系统自己调用的
出现异常与否 不会影响到 finally的执行
也就是说 finally一定会执行
finally的作用: 一般用来敢比资源 例如:关闭流合数据库
public static void fun() {
try {
System.out.println( 10 / 0);
return;
} catch (Exception e) {
System.out.println("你除以0了");
}finally {
System.out.println("我是finally");
}
System.out.println("哈哈");
}
这里最后打印的结果是 "你除以0了" "我是finally" "哈哈"
从这里可以看出 就算用return结束这个方法 finally也会被打印
class TestFinally{
public int fun() {
int num = 10;
try {
num = 20;
System.out.println(10 / 0);
return num;
} catch (Exception e) {
num = 30;
return num;
}finally {
num = 40;
}
}
}
这里打印的是 30
运行时异常 和编译时异常
运行时异常是程序员编写的代码出错了
编译时异常是为了这个可能发生才错误做的提前准备,也就是编写程序时报红
public class Demo{
public static void main(String[] args){
FileInputStream inputStram = new FileInputStream("s.txt");
fun;
}
}
public static void fun(){
try{
FileInputStream inputStream = new FileInputStream("s.txt");
}catch(Exception e){
System.out.println("没有这个文件");
}
}
手动抛出异常
public class Demo06 {
public static void main(String[] args) throws Exception {
Person person = new Person();
person.setName("a");
person.setAge(121);
System.out.println(person);
}
}
class Person{
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) throws Exception {
if (age <= 120 && age >= 0) {
this.age = age;
}else {
Exception e = new Exception("年龄超出范围");
throw e;
throw new Exception("年龄超出范围");
}
}
@Override
public String toString() {
return "[name=" + name + ", age=" + age + "]";
}
}
public class Demo {
public static void main(String[] args) throws Exception {
Person person = new Person();
person.setName("a");
person.setAge(121);
System.out.println(person);
}
class Person{
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) throws Exception{
if(age <= 120 && age >= 0 ){
this.age = age;
}else{
throw new AgeOutOfBoundsException("年龄超出范围")
}
}
@Override
public String toString() {
return "[name=" + name + ", age=" + age + "]";
}
}
class AgeOutOfBoundsException extends Exception{
public AgeOutOfBoundsException() {
}
public AgeOutOfBoundsException(String message) {
super(message);
}
}
Throwable中的方法
public static void main(String[] args) {
Exception exception = new Exception("这里可以写错误信息");
String message = exception.getMessage;
exception.printStackTrace();
}
Day.21
http://blog.youkuaiyun.com/ssssssue