异常

介绍

  • 概念: 异常,就是不正常情况;程序中出现不符合预期的情况就是异常;
  • 作用:
  • 可以针对程序中出现的问题作出相应处理,提高程序健壮性;
  • 在程序中发生异常的地方通过日志技术将问题记录下来,帮助开发者快速排查错误;

异常体系&分类

  • 体系
  • Throwable:java异常体系的最高父类;java中所有可被抛出、捕获或声明的异常类,都要继承这个类或它的子类;
  • Error:错误,表示程序中严重的不能被JVM处理的问题;遇到这种问题,JVM都会停止运行;
  • Exception:异常,表示程序中可以被JVM处理的问题;如果程序中抛出该类或它的子类的异常,编译时就会检查有没有书写处理的代码;如果没有写,就会报错;
  • RuntimeException:表示运行时异常;该类和它的子类表示的异常,在编译期不会检查;
  • RuntimeException:表示编译期异常;
  • 分类
  • 编译期异常
  • 概念:指的是Exception及其子类(不包括RuntimeException和它的子类)表示的异常;
  • 特点:如果在程序中使用throw关键字显示的抛出这类异常,编译时编译器会检查有没有书写处理代码,如果没有就会报错;(也就是说,程序中如果抛出这类异常,必须处理)
  • 运行期异常:
  • 概念:指的是RuntimeException和它的子类表示的异常;
  • 特点:如果程序中使用throw关键字显示的抛出这类异常,不管书写处理代码没有,编译时编译器都不管;

编译期异常和运行期异常,指的是编译的时候,是否检查书写了处理代码;

  • 图解:

java中异常有什么用 java异常的作用_基础

自定义异常

因为JDK中提供的异常类太多,不方便记忆和使用,所以需要自定义异常

Error,表示 程序中严重的不应该处理的问题;

Exception,表示程序中应该自己能够处理的问题;

所以,一般自定义异常,可以继承Exception,而不要去继承Error;

  • 自定义异常的步骤:
  • 1、定义一个类,让它继承ExceptionRuntimeException
  • 2、创建一个构造函数,接收一个表示异常信息的参数;
  • 3、调用父类的有参构造函数,将接收的异常信息传递给父类的构造函数;
  • 示例:
//需求:创建一个描述人的信息的类,需要对年龄的合法性进行判断;

class WrongAgeException extends RuntimeException{
	WrongAgeException(){}
	WrongAgeException(String errMsg){
		 super(errMsg);
	}
}

class Person{
	private int age;
	public void setAge(int age){
		if(age >= 1 && age <= 150){
			this.age = age;
		}else{
			//实际上,如果数据不合法程序就不应该继续向下执行;所以这里应该抛出异常;
			throw new WrongAgeException("输入的年龄"+age+"不合法,正确的范围应该是1(包含)到150(包含)");
		}
	}
	public int getAge(){
		return age;
	}
	public Person(int age){
		setAge(age);//调用函数赋值,可以在创建对象时也对传入的年龄参数进行检验
	}
	//重写toString函数,目的是可以直接输出这个对象的属性值
	public String toString(){
		return "年龄:"+age;
	}
}

//测试
class Test{
	public static void main(String[] args) {
		Person p = new Person(-10);	
		System.out.println(p);
		p.setAge(-2);
		System.out.println(p);
	}
}

异常的处理

  • 异常的声明:如果程序不能自己解决出现的问题,就可以使用throws关键字,在函数的参数列表后面、函数体大括号前面将异常的类型声明出去,目的时告诉调用者,这个函数执行时有可能会出现什么问题;这种处理方法就叫做异常的声明;

自己不处理,告诉调用者,自己可能出什么问题,真出了问题,就将问题抛给调用者;

  • 异常的捕获:如果程序中出现的问题可以自己解决,就可以使用try-catch代码块,将可能出错的代码包起来,然后书写处理代码;这种处理方式叫做异常的捕获;

自己直接将问题解决,不惊动调用者;

看具体情况;一般如果问题是因为传入的参数不合法造成的,就应该使用异常的声明;否则应该使用捕获;

异常部分细节

  • throwthrows的区别
  • throw:用来在函数里面抛出异常对象;
  • throws:用来声明函数会抛出异常;
  • finally代码块

一般在捕获异常时,在try-catch代码块后面还可以添加一个finally代码块,

作用是:在finally块中的代码,一定会被执行;

一般再开发中,有些工作一定要执行的,都会放到finally代码块中完成;

  • trycatchfinally允许的组合
  • 必须有try代码块;
  • 三个代码块都不能单独存在;
  • ry可以和其它两个单独组合,也可以三个一起使用;
  • catch可以多次出现;
  • 继承中方法重写的异常

子类重写父类函数,不能比父类函数声明更多编译期异常;

  • 父类方法没有声明异常,子类重写的方法不能声明编译时异常
  • 父类方法声明了一个编译异常,子类重写的方法只能声明这个异常或它的子异常
  • 父类方法声明了多个编译异常,子类重写的方法只能声明这些异常的子集或子集的子类

  • 当才华还配不上野心,就静下来学习
  • blog地址:hangzhi.site