java基础2:异常
异常的继承体系
Throwable: 它是所有错误与异常的超类(祖宗类)
|- Error 错误
|- Exception 编译期异常,进行编译JAVA程序时出现的问题
|- RuntimeException 运行期异常, JAVA程序运行过程中出现的问题
1,没有对异常进行处理时异常的处理机制
2,抛出异常 throw,throws
* 异常中的关键字
* throw,在方法内部,抛出异常的对象
* throw 后面,必须写new 对象,必须是异常的对象,必须是Exception或者子类
*
* 方法中声明异常关键字
* throws 用于在方法的声明上,标明次方法,可能出现异常
* 请调用者处理
* throws 后面必须写异常类的类名
*
* 调用了一个抛出异常的方法,调用者就必须处理
* 不处理,编译失败
public class ExceptionDemo {
public static void main(String[] args) throws Exception {
int[] arr = {};
int i = getArray(arr);
System.out.println(i);
}
//对数组的最后索引*2,返回
public static int getArray(int[] arr) throws Exception {
//对方法参数进行合法性的判断,进行判断是不是null
if( arr == null){
//抛出异常的形式,告诉调用者
//关键字 throw
throw new Exception("传递数组不存在");
}
//对数组进行判断,判断数组中,是不是有元素
if(arr.length == 0){
//抛出异常的形式,告诉调用者,数组没有元素
throw new Exception("数组中没任何元素");
}
int i = arr[arr.length-1];
return i*2;
}
}
这里在getArray方法中定义了异常,相当于自己肚子疼,一旦出现异常,后面的都不执行。方法声名throws 为抛出异常给调用者main,相当于向上级反映自己肚子疼,而上级main无法处理,也抛出,最后给了jvm处理
3,try...catch 自己处理异常,避免程序终止
4,运行时异常
l RuntimeException和他的所有子类异常,都属于运行时期异常。NullPointerException,ArrayIndexOutOfBoundsException等都属于运行时期异常.
l 运行时期异常的特点:
l 方法中抛出运行时期异常,方法定义中无需throws声明,调用者也无需处理此异常
l 运行时期异常一旦发生,需要程序人员修改源代码.
class ExceptionDemo{
public static void main(String[] args){
method();
}
public static void method(){
throw new RuntimeException();
}
}
运行时异常和编译异常不同的是运行异常发生,程序终止。比如求圆面积
* 定义方法,计算圆形的面积
* 传递参数0,或者负数,计算的时候没有问题
* 但是,违反了真实情况
* 参数小于=0, 停止程序,不要在计算了
*/
若定义编译异常,程序还会执行这种无意义操作
5,子类继承父类重写时的异常处理
/*
* 继承后,在子类重写父类方法的时候,异常处理
* 结论:
* 父类的方法,如果抛出异常,子类重写后
* 可以不抛出异常
* 也可以抛出异常,但是,如果子类要抛,抛出的异常不能大于父类的异常
* 大于,都指的是继承关系
*
* 父类的方法,没有异常抛出,子类重写后
* 也不能抛出异常
* 如果子类中调用了抛出异常的方法,别无选择,只能try..catch处理
*/
6,Throwable类中的方法
* 三个方法,都和异常的信息有关系
* String getMessage() 对异常信息的详细描述 异常了!
* String toString() 对异常信息的简短描述 java.lang.Exception: 异常了!
* void printStackTrace() 将异常信息追踪到标准的错误流 异常信息最全,JVM默认调用方法也是这个方法
*/
7,自定义异常
*需求:求平均值,使用int ... source传递可变参,出现负数时,需要停止运行,抛出自定义的负数异常
创建异常类,继承RuntimeException
class MyException extends RuntimeException{
/*
为什么要定义构造函数,因为看到Java中的异常描述类中有提供对异常对象的初始化方法。
*/
MyException(){
super();
}
MyException(String message){
super(message);// 如果自定义异常需要异常信息,可以通过调用父类的带有字符串参数的构造函数即可。
}
}
总结一下,构造函数到底抛出这个NoAgeException是继承Exception呢?还是继承RuntimeException呢?
l 继承Exception,必须要throws声明,一声明就告知调用者进行捕获,一旦问题处理了调用者的程序会继续执行。
l 继承RuntimeExcpetion,不需要throws声明的,这时调用是不需要编写捕获代码的,因为调用根本就不知道有问题。一旦发生NoAgeException,调用者程序会停掉,并有jvm将信息显示到屏幕,让调用者看到问题,修正代码。