异常
Java代码在运行时期发生的问题就是异常。在Java中,把异常信息封装成了一个类。当出现了问题时,就会创建异常类对象并抛出异常相关的信息(如异常出现的位置、原因等)。
异常继承体系:
Throwable: 它是所有错误与异常的超类(祖宗类)
|- Error 错误
|- Exception 编译期异常,进行编译JAVA程序时出现的问题
|- RuntimeException 运行期异常, JAVA程序运行过程中出现的问题
异常与错误的区别:
异常:指程序在编译、运行期间发生了某种异常(XxxException),我们可以对异常进行具体的处理。若不处理异常,程序将会结束运行。
错误:指程序在运行期间发生了某种错误(XxxError),Error错误通常没有具体的处理方式,程序将会结束运行。Error错误的发生往往都是系统级别的问题,都是jvm所在系统发生的,并反馈给jvm的。我们无法针对处理,只能修正代码。
public static void main(String[] args) { //该句运行时发生了内存溢出错误OutOfMemoryError,开辟了过大的数组空间,导致JVM在分配数组空间时超出了JVM内存空间,直接发生错误。 }
1、抛出异常throw
在java中,提供了一个throw关键字,它用来抛出一个指定的异常对象。
-
1,创建一个异常对象。封装一些提示信息(信息可以自己编写)。
-
2,需要将这个异常对象告知给调用者。
throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。
使用格式:
throw new 异常类名(参数);
2、声明异常throws
将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,而没有进行捕获处理,那么必须通过throws进行声明,让调用者去处理。
声明异常格式:
修饰符返回值类型方法名(参数) throws 异常类名1,异常类名2… { }
/* * 异常中的关键字 * throw,在方法内部,抛出异常的对象 * throw 后面,必须写new 对象,必须是异常的对象,必须是Exception或者子类 * * 方法中声明异常关键字 * throws 用于在方法的声明上,标明次方法,可能出现异常 * 请调用者处理 * throws 后面必须写异常类的类名 * * 调用了一个抛出异常的方法,调用者就必须处理 * 不处理,编译失败 */ public class ExceptionDemo { // main方法在往上(JVM)报告这个异常 public static void main(String[] args) throws Exception { int[] arr = {}; int i = getArray(arr); System.out.println(i); } //使用throws声明异常,报告给调用者 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; } }
3、捕获异常
Java中对异常有针对性的语句进行捕获,可以对出现的异常进行指定方式的处理
/* * 异常的处理方式: * try...catch...finally * 格式: * try{ * 被检测的代码 * 可能出现异常的代码 * }catch(异常类名 变量){ * 异常的处理方式 * 循环,判断,调用方法,变量 * }finally{ * 必须要执行代码 * } */ public class ExceptionDemo1 { public static void main(String[] args) { int[] arr = null; try{ int i = getArray(arr); System.out.println(i); }catch(NullPointerException ex){ // 多异常捕获的时候,在上面的等级必须要小于等于下面的等级 System.out.println("###"+ex); }catch(ArrayIndexOutOfBoundsException ex){ System.out.println("!!!!!!"+ex); }finally{ System.out.println("Game Over"); } } /* * 定义方法,抛出异常 * 调用者使用try catch */ public static int getArray(int[] arr)throws NullPointerException,ArrayIndexOutOfBoundsException{ //对数组判空 if( arr == null){ //手动抛出异常,抛出空指针异常 throw new NullPointerException("数组不存在"); } //对数组的索引进行判断 if( arr.length < 3){ //手动抛出异常,抛出数组的索引越界异常 throw new ArrayIndexOutOfBoundsException("数组没有3索引"); } return arr[3]+1; } }
Throwable类中的方法
三个方法,都和异常的信息有关系
- String getMessage() 对异常信息的详细描述 异常了!
- String toString() 对异常信息的简短描述 java.lang.Exception: 异常了!
- void printStackTrace() 将异常信息追踪到标准的错误流 异常信息最全,JVM默认调用方法也是这个方法
运行时异常
运行时异常不用声明,也不用捕获
/* * 异常分为编译异常和运行时期异常 * 编译异常: 调用了抛出异常的方法,不处理编译失败 (try throws) * 运行异常: 抛出的异常是RuntimeException类,或者是他的子类 * * 运行异常的特点: * 方法内部抛出的异常是运行异常, new XXXException * 方法的声明上,不需要throws语句,调用者,不需要处理 * 设计原因: * 运行异常,不能发生,但是如果发生了,程序人员停止程序修改源代码 * * 运行异常: 一旦发生,不要处理,请你修改源代码, 运行异常一旦发生,后面的代码没有执行的意义 */ public class RuntimeExceptionDemo { public static void main(String[] args) { double d = getArea(1); System.out.println(d); } /* * 定义方法,计算圆形的面积 * 传递参数0,或者负数,计算的时候没有问题 * 但是,违反了真实情况 * 参数小于=0, 停止程序,不要在计算了 */ public static double getArea(double r){ if(r <= 0){ throw new RuntimeException("圆形不存在"); } return r*r*Math.PI; } public static void function(){ int[] arr = {1,2,3}; //对数组的5索引进行判断,如果5索引大于100,请将5索引上的数据/2,否则除以3 //索引根本就没有 if(arr[5] > 100){ arr[5] = arr[5]/2; }else{ arr[5] = arr[5]/3; } }
继承的异常问题
如果父类中的方法声明了异常,子类重写后,可以声明异常(声明的异常必须等级小于等于父类)也可以不声明异常。
如果父类中的方法中没有声明异常,子类重写后,不可以声明异常。
4、自定义异常
一般我们自定义的异常都是继承于RuntimeException,不用声明,也不用捕获。
ExceptionDemo.java
public class ExceptionDemo { public static void main(String[] args) { int avg = getAvg(50,60,-70,80); System.out.println(avg); } /* * 传递成绩,计算成绩的平均数 * 成绩没有负数,需要抛出异常,停止运算 */ public static int getAvg(int...source){ int sum = 0 ; for(int s : source){ if( s < 0){ throw new FuShuException("成绩错误 "+s); } sum = sum + s; } return sum/source.length; } }
FuShuException.java
/* * 自定义异常 * 继承Exception,或者继承RuntimeException * 构造方法中,super将异常信息,传递给父类 */ public class FuShuException extends RuntimeException{ public FuShuException(String s){ super(s); } public FuShuException(){} }