每次出现异常,对相应的异常我们需要去API中查找他的名字和构造方法,这样极其不方便,查找和在代码阅读时也很不方便,
异常本来就是一个包含了问题信息的类
所以我们完全可以自定义异常:异常名字,问题信息包括异常位置信息
当如下自定义使用后:
class IllegalParameterException extends Exception{
//多种构造函数
IllegalParameterException(){}//空参
IllegalParameterException(String s){}//字符串
}
throw new IllegalParameterException("传入的年龄不合法!!");
会有编译错误:不兼容类型,需要throwable
查找Java的API文档会发现:throwable 是一个超类,他的子类有:Error Exception。
可以看出异常是成体系的,而throw 是体系的顶层
通过阅读可得:自定义异常被抛出,必须继承Throwable 的子类,由此创建的对象才能被throw抛出——这是异常体系具备的特性:可抛行——可被关键字:throw 操作
继承之后还是有编译错误:未报告错误;必须对其进行捕获或是声明
通过尝试和阅读API 异常继承体系发现:继承RuntimeException 程序可以执行
RuntimeException:
class IllegalParameterException extends RuntimeException{//!!!重点就在于异常的继承
为什么要这样继承:(查看Java的源码).。但这样写运行时没有异常内容,为什么会出现这样的区别,可以查看异常体系的源码,会发现出入的字符串一直都在向上传递:super(message);
代码不难重要的是学习这种思考解决问题的方式
完全正确的代码(自定义异常):
class IllegalParameterException extends RuntimeException{//!!!重点就在于异常的继承
//多种构造函数
IllegalParameterException(){
super();
}//空参
IllegalParameterException(String s){
super(s);
}//字符串
throw new IllegalParameterException("传入的年龄不合法!!");
总结:自定义运行时异常只需要做两点:继承一个RuntimeException 类或者是他的子类/(为什么需要继承:异常成体系/需要继承父类对内容的处理)
在构造函数中调用父类的构造函数
——————————————————————————————————————————————————————
解决上述遗留问题:
1.继承Exception 和继承RuntimeException 为什么差距如此之大
2.什么是捕获,什么是说明
Exception :是编译时的错误,语法错误,该程序已经出现了问题,Java认为这个程序出现了隐患,要么你就捕获要么你就声明(要么解决问题,要么将问题标识出来让调用者知道)
throw new Exception(); 编译会出错/异常需要捕获/声明
throw new RuntimeException(); 编译不会出错——原因:在Java中将异常分出一类,运行时异常,就不需要捕获或者声明,这一类具体为运行异常:这个异常不是因为这个功能本身发生的异常,而是因为比如调用者传递参数错误而的导致的功能运行失败(改变了功能的正常状态)这个时候也是问题需要通过异常来体现但是不需要声明/捕获。
声明的目的:为了让调用者来进行处理。
不声明的目的:不需要调用者来处理,就只是为了让程序停止并且让调用者看到现象并且修正
{可以想到Error/错误:也是显示让调用者修改代码,但这是底层错误比较重大,异常是在正常范围内的}
可得:
异常分为两种:编译会检测到的异常(语法类):要捕获/声明(throws)
运行时的异常:不需要捕获或者声明(RuntimeException及其子类)
常见异常:
ArrayIndexOutBoundsExcepyion:数组下标越界
IllegalArgumentException:非法参数
NullPointerException:空
ClassCastException:对象类型强制转换错误
——————————————————————————————————————————————————————
下一章讲异常的捕获和声明