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 }
|