java学习中,异常和错误的简介、捕获异常、抛出异常、自定义异常、finally关键字(java 学习中的小记录)
java学习中,异常和错误的简介、捕获异常、抛出异常、自定义异常、finally关键字(java 学习中的小记录)
作者:王可利(Star·星星)
异常:(API 的 java.lang 有一个异常,有很多很多)
在Java程序中也会程序出现不正常的情况,这个就叫异常。
Java是面向对象的语言,任何事物都可以用类来描述,同样的异常也是一种事物。Java中提供了很多的异常类。
多个异常堆积起来,就是一个异常体系。
Throwable:是异常类的父类,超类。Exception 异常、error错误。
异常的体系如下(图解):
主要学习Thorwable 的三个方法:
1.toString(); 对Thorwable 的简短描述:类完整的名称: 包名 + 类名
2.getMessage(); Thorwable的详细信息的字符串
3.printStackTrace(); 打印的是异常的栈内存信息
package study; public class star { public static void main(String[] args) { Throwable t = new Throwable("这是一个异常,请处理");//这里是异常对象,所以异常//参数可以传一个getMessage进来 System.out.println(t.toString());//java.lang.Throwable:这是一个异常,请处理 System.out.println(t.getMessage());//这是一个异常,请处理 t.printStackTrace();//打印的是异常的栈内存信息 } }
error 错误:错误一般是Java虚拟机或者硬件导致的问题,叫错误。所以我们一般不会用代码来处理错误。
如:byte[] buf = new byte[1024*1024*1024];
//语法没有错误,java虚拟机默认只能管理64M内存,所以是因为java或者硬件引发的问题我们叫错误
异常Exception:所有的异常都 继承于 Exception。
错误和异常的区别:
如:java.lang.OutOfMemoryError 这个是错误的一种类型(以Error结尾的)
AclNotFoundException 这个是一个异常(以Exception结尾,除了Error结尾的都是)
异常的处理:
方式一:捕获异常
捕获异常的处理格式:
try{
可能发生异常的代码
}catch(捕获的异常的类型 变量名){
处理异常的代码
}
1 package study; 2 3 4 public class star { 5 public static void main(String[] args) { 6 7 int[] arr = {1,2}; 8 arr= null;//java.lang.NullPointerException 空指针异常 9 test(4, 0,arr);//java.lang.ArithmeticException: / by zero 10 } 11 public static void test(int a,int b,int[] arr){ 12 13 14 //捕获异常处理 15 int c = 0; 16 17 try { 18 //可能出现异常的代码 19 System.out.println(arr.length); 20 c = a/b; 21 } catch (ArithmeticException e1) { 22 System.out.println("处理除数为0的异常"); 23 } catch(NullPointerException e2){ 24 System.out.println("处理空制指针异常"); 25 } catch(Exception e){//这个父类的要放在最后面,如果放在最前面处理了异常了,后面的异常都不会执行了。这样这个可以处理上面没有的其他异常。 26 System.out.println("所有的异常都在这里处理"); 27 } 28 29 System.out.print("c = "+c); 30 } 31 }
捕获异常处理的注意点:
1.如果try中的方法出了问题,处理之后会继续执行try-catch 以外的代码。
2.catch里面的代码只会在 try中的代码出现异常了,才会执行。
3.一个try中是可以用很多个catch块,也就是会说一个try可以处理很对个异常。
4.try 捕获异常是从小到大的顺序来的捕获异常的。最下面的是父类最大的异常。否者就会报错。
捕获异常的作用:
目前还看不出,学习JavaEE的时候就经常用到(知识点后期补上);
为什么不直接用最大的异常:
为了让我们跟精确快速地找到错误的根源。如:空指针异常,用最大的异常的话,就看不出来是空指针异常。
方式二:抛出异常
抛出异常处理关键的两个关键字(throw 、throws)
throw 、throws使用注意点:
1.throw 关键字用于方法里面,throws 用于方法声明上的。
2.throw 关键字用于方法内部抛出异常,throws 用于方法声明上抛出异常。
3.throw 关键字后面只能有一个异常,throws 可以声明多个异常。
抛出异常的使用注意点:
1.如果你在方法中抛出了一个异常对象,就必须在方法声明上一个异常的抛出。
2.如果一个方法调用了抛出异常的方法,那么调用者就必须处理抛出的这个异常。
3.如果一个方法中跑出了异常,那么throw后面的代码不会再被执行。
4.在一种情况下只能抛出一种异常。(详见代码)如果是多个异常的话,就取离它最近的那个异常。
什么时候抛异常,什么时候不抛异常?
需要通知调用者(谁调用你的代码),你的代码可能存在问题,,这个时候就需要抛出这个异常,让调用者来解决处理。
如果代码是直接和用户打交道的,这个时候遇到异常,就需要处理代码,用户不知道这个代码是什么意思,要换个方式让用户知道这个是什么。
1 package study; 2 3 4 public class star { 5 public static void main(String[] args) { 6 try { 7 int[] arr = {1,2}; 8 arr = null; 9 test(4, 0,arr); 10 } catch (ArithmeticException e) { 11 System.out.println("正在处理异常"); 12 } 13 14 } 15 public static void test(int a ,int b,int[] arr) throws ArithmeticException,NullPointerException{//一定要声明这个异常 16 //之前用try-catch 是用来处理异常,然后后面的代码继续执行 17 //现在是把出现异常的代码抛出去,给调用者(这里的上一级在主函数里面) 18 19 if (b == 0) { 20 throw new ArithmeticException();//有可能有这个错误的对象,把它抛出去 21 }/*else if (arr == null) {//如果上面执行了代码之后, throw后面的代码就不会再执行 22 throw new NullPointerException(); 23 } */ 24 25 System.out.println("啦啦啦"); 26 int c = a/b; 27 //System.out.println(c);//抛出去的话 c 就没有意义了,就不用打印 28 } 29 }
自定义异常
需求:模拟feiQ(飞秋)上线的时候,发现网线没有插,这个时候要自己抛出异常(提示程序员网线没有插);
前提:自定义一个类继承于Exception
问题:有时候抛出异常必须声明,有时候抛出异常不需要声明。
异常体系结构:在 Exception 后面还分为 运行时异常 和 编译时异常;
运行是异常:抛出运行时异常时,是可以不用在方法上声明异常的,调用者也可以不作处理。
编译时异常:抛出编译时异常时,就必须在方法方法上声明异常,调用者也必须要处理一下。
如何区分编译时和运行时异常:
那些属于运行时异常:是RuntimeException 这个异常本身,或者继承于这个异常的子类都是运行时异常。
除了运行时异常其他的都是编译时的异常。Exception 是编译时的异常。
1 class NoIPException extends Exception{ 2 3 //自定义没插网线的异常 4 public NoIPException(String message) { 5 super(message);//如果不写默认调用父类的空的构造方法 6 } 7 } 8 9 public class star { 10 public static void main(String[] args) throws NoIPException{ 11 12 //用feiQ 13 String ip = "192.168.10.100"; 14 15 test(ip);//这里错误,两个选择,可以继续抛,可以处理掉。 16 throw new NoIPException("没插好,网线请插好网线");//这里再抛出就是去到了java虚拟机了 17 } 18 public static void test(String ip) throws NoIPException{ 19 if (ip == null) { 20 throw new NoIPException("没插好,网线请插好网线");//这里抛出了给调用者(主函数) 21 } 22 } 23 }
finally 关键字
finally 块 和 try 是一起使用的。
finally:无论出现什么问题,finally 中的代码都会执行,除非jvm退出了,代码才不会被执行。
finally 的作用:finally 非常适合做资源释放的工作,这样做就可以保证我这资源文件在任何时候都可以释放。
1 package study; 2 3 public class star { 4 public static void main(String[] args) { 5 try{ 6 7 test(10,0); 8 9 }catch(Exception e) { 10 11 System.out.println("正在处理...."); 12 } 13 } 14 public static void test (int a, int b) throws Exception{ 15 16 int c= 0; 17 try 18 { 19 c = a / b; 20 } 21 catch (Exception e) 22 { 23 24 // System.exit(0);//退出jvm 25 return; //还是照样执行finally中的代码 26 } 27 finally { 28 System.out.println("c = "+c); 29 } 30 } 31 }