java中将所有的异常封装成对象,当运行时发现问题,就将通过关键字throw将异常对象抛出
public class Demo { public static void main(String[] args) { int[] arr = new int[3]; show(arr,3); } public static void show(int[] arr,int index) { if(index >=3 ) { throw new ArrayIndexOutOfBoundsException("角标过大"); } System.out.println(arr[index]); } }
自定义异常:
public class Demo { public static void main(String[] args) throws ArrayNegIndexException { int[] arr = new int[3]; show(arr,-3); } public static void show(int[] arr,int index) throws ArrayNegIndexException { if(index >=3 ) { throw new ArrayIndexOutOfBoundsException("角标过大"); } if(index <0 ) { throw new ArrayNegIndexException("角标为负数了"); } System.out.println(arr[index]); } } class ArrayNegIndexException extends Exception //自定义异常类,并继承了Exception { ArrayNegIndexException() { } ArrayNegIndexException(String msg) { super(msg); } }
我们发现第一个代码并没有使用throws而第二个却使用throws在函数与main函数上进行声明抛出,这两者的区别需要注意一下。
首先异常分为两种:
1,编译时可以检测的异常:Exception和其子类都是,除了RuntimeException这个子类不是。
这种异常必须设置专门的处理方法
这类异常可以不用去捕获处理,Java虚拟机会进行处理,比如空指针异常
2,编译时不会被检测的异常:RuntimeException和其子类
这种异常通常是在Java虚拟机正常运行时发生的,一般是因为调用者调用不当造成的。
这类异常必须捕获处理,不然编译不能通过。
如果我们自定义异常类继承RuntimeEception的话就不用进行声明抛出了
public class Demo { public static void main(String[] args) { int[] arr = new int[3]; show(arr,-3); } public static void show(int[] arr,int index) { if(index >=3 ) { throw new ArrayIndexOutOfBoundsException("角标过大"); } if(index <0 ) { throw new ArrayNegIndexException("角标为负数了"); } System.out.println(arr[index]); } } class ArrayNegIndexException extends RuntimeException //继承的是运行时异常 { ArrayNegIndexException() { } ArrayNegIndexException(String msg) { super(msg); } }
throw与throws区别:
throws使用在函数上 throw使用在函数内部
throws抛出的是异常类 可以抛出多个 使用逗号隔开 throw抛出的是异常对象 一次只能抛出一个
使用try catch捕获异常
格式:
try
{
异常代码
}
catch(异常类 异常对象引用)
{
针对异常的处理代码
}
finally
{
//finally可写可不写
}
public class Demo { public static void main(String[] args) { int[] arr = new int[3]; System.out.println("开始执行..."); show(arr,-3); System.out.println("继续进行..."); } public static void show(int[] arr,int index) { System.out.println(arr[index]); } }
我们发现没有捕获异常,程序在异常代码处就停止不再执行下面的代码
public class Demo { public static void main(String[] args) { int[] arr = new int[3]; System.out.println("开始执行..."); try { show(arr,-3); } catch(ArrayNegIndexException e) { System.out.println("角标为负数了!!"); } System.out.println("继续进行..."); } public static void show(int[] arr,int index) throws ArrayNegIndexException { if(index<0) { throw new ArrayNegIndexException(); } System.out.println(arr[index]); } } class ArrayNegIndexException extends Exception { ArrayNegIndexException() { } ArrayNegIndexException(String msg) { super(msg); } }
我们发现捕获异常之后,在进行处理代码之后继续进行执行后续代码。
异常处理的原则:
1,函数内部如果出现需要检测的异常,就throw这个异常对象,然后要么声明抛出,要么使用try catch捕获,否则编译失败
2,如果调用了声明异常的函数,要么声明抛出,要么try catch捕获否则编译失败
3,在catch内进行处理代码能解决的就是用catch,不能解决的就向上throws给调用者
4,一个功能抛出多个异常就是用多个catch来进行针对性处理
异常处理的注意事项:
1,子类在覆盖父类的方法时,父类的方法如果抛出了异常 ,那么子类的方法只能抛出父类异常或者父类异常的子类
2,如果父类抛出多个异常,那么子类只能抛出父类异常的子集
3,如果父类方法没有抛出异常,那么子类方法就不能声明抛出异常(注意是不能使用throws,但是可以再函数内部使用throw 来抛出RuntimeException异常),对于检查异常可以进行try