码迷,mamicode.com
首页 > 编程语言 > 详细

Java基础(55):Exception类详解(转)

时间:2016-04-15 19:59:17      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:

             Java中的异常 Exception

java.lang.Exception类是Java中所有异常的直接或间接父类。即Exception类是所有异常的根类。

  比如程序:

 1 public class ExceptionTest
 2 {
 3       public static void main(String[] args)
 4       {
 5              int a = 3;
 6              int b = 0;
 7              int c = a / b;          
 8              System.out.println(c);
 9       }
10 }

编译通过,执行时结果:

  Exception in thread "main" java.lang.ArithmeticException: / by zero

     at com.learnjava.exception.ExceptionTest.main(ExceptionTest.java:9)

  因为除数为0,所以引发了算数异常。

比较常见的异常还有这种:空指针异常

  java.lang.NullPointerException是空指针异常,出现该异常的原因在于某个引用为null,但却调用了它的某个方法,这时就会出现该异常。

Java中的异常分为两大类:

  1.Checked Exception(非Runtime Exception

  2.Unchecked ExceptionRuntime Exception

运行时异常

  RuntimeException类是Exception类的子类,它叫做运行时异常,Java中的所有运行时异常都会直接或者间接地继承自RuntimeException类。

  Java中凡是继承自Exception,而不继承自RuntimeException类的异常都是非运行时异常

   异常处理的一般结构

 1 try
 2     {
 3          // 可能发生异常的代码
 4         // 如果发生了异常,那么异常之后的代码都不会被执行
 5     }
 6     catch (Exception e)
 7     {
 8         // 异常处理代码
 9     }
10     finally
11     {
12         // 不管有没有发生异常,finally语句块都会被执行
13     }

比如本文最开始的除法运算代码,加入异常处理之后:

 1 public class ExceptionTest
 2 {
 3     public static void main(String[] args)
 4     {
 5         int c = 0;
 6         try
 7         {
 8             int a = 3;
 9             int b = 0;
10 
11             // 这块代码出现了异常
12             c = a / b;
13 
14             // 那么异常之后的代码都不会被执行
15             System.out.println("Hello World");
16         }
17         catch (ArithmeticException e)
18         {
19             e.printStackTrace();
20         }
21         finally
22         {
23             //不管有没有发生异常,finally语句块都会被执行
24             System.out.println("Welcome");
25         }
26 
27         System.out.println(c);
28         // 当b为0时,有异常,输出为c的初始值0
29     }
30 }

多个catch

  一个try后面可以跟多个catch,但不管多少个,最多只会有一个catch块被执行。

异常处理方法

   一.对于非运行时异常(checked exception),必须要对其进行处理,否则无法通过编译。

  处理方式有两种:

  1.使用try..catch..finally进行捕获;

  2.在产生异常的方法声明后面写上throws 某一个Exception类型,如throws Exception,将异常抛出到外面一层去。

  对非运行时异常的处理详见代码例子:

  处理方式1:将异常捕获

 1 将异常捕获
 2 
 3 public class ExceptionTest2
 4 {
 5     public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
 6     {
 7         System.out.println("Hello World");
 8 
 9         // 抛出异常
10         throw new Exception();
11     }
12 
13     public static void main(String[] args)
14     {
15         ExceptionTest2 test = new ExceptionTest2();
16 
17         try
18         {
19             test.method();
20         }
21         catch (Exception e)
22         {
23             e.printStackTrace();
24         }
25         finally
26         {
27             System.out.println("Welcome");
28         }
29 
30 
31     }
32 
33 }

    处理方式2:将异常继续向外抛出

 1 将异常抛出
 2 
 3 public class ExceptionTest2
 4 {
 5     public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
 6     {
 7         System.out.println("Hello World");
 8 
 9         // 抛出异常
10         throw new Exception();
11     }
12 
13     public static void main(String[] args) throws Exception // main方法选择将异常继续抛出
14     {
15         ExceptionTest2 test = new ExceptionTest2();
16 
17         test.method(); // main方法需要对异常进行处理
18 
19         // 执行结果:
20         // Hello World
21         // Exception in thread "main" java.lang.Exception
22         // at com.learnjava.exception.ExceptionTest2.method(ExceptionTest2.java:10)
23         // at com.learnjava.exception.ExceptionTest2.main(ExceptionTest2.java:17)
24     }
25 
26 }

对于运行时异常(runtime exception),可以对其进行处理,也可以不处理。推荐不对运行时异常进行处理。

自定义异常

  所谓自定义异常,通常就是定义一个类,去继承Exception类或者它的子类。因为异常必须直接或者间接地继承自Exception类。

  通常情况下,会直接继承自Exception类,一般不会继承某个运行时的异常类。

  自定义异常可以用于处理用户登录错误,用户输入错误提示等。

  自定义异常的例子:

  自定义一个异常类型

 1 public class MyException extends Exception
 2 {
 3     public MyException()
 4     {
 5         super();//继承父类的默认构造函数
 6     }    
 7     public MyException(String message)
 8     {
 9         super(message);
10     }
11 }

一种异常处理方式:

 1 一种异常处理方式
 2 
 3 public class ExceptionTest4
 4 {
 5 
 6     public void method(String str) throws MyException
 7     {
 8         if(null == str)
 9         {
10             throw new MyException("传入的字符串参数不能为null!");
11         }
12         else
13         {
14             System.out.println(str);
15         }
16     }
17     
18     public static void main(String[] args) throws MyException //异常处理方式1,不断向外抛出
19     {
20         ExceptionTest4 test = new ExceptionTest4();
21         test.method(null);
22     }
23 }

另一种异常处理方式(更常用):

 1 异常处理方式二
 2 
 3 public class ExceptionTest4
 4 {
 5 
 6     public void method(String str) throws MyException
 7     {
 8         if (null == str)
 9         {
10             throw new MyException("传入的字符串参数不能为null!");
11         }
12         else
13         {
14             System.out.println(str);
15         }
16     }
17 
18     public static void main(String[] args)
19     {
20         //异常处理方式2,采用try...catch语句
21         try
22         {
23             ExceptionTest4 test = new ExceptionTest4();
24             test.method(null);
25 
26         }
27         catch (MyException e)
28         {
29             e.printStackTrace();
30         }    
31         finally
32         {
33             System.out.println("程序处理完毕");
34         }
35 
36     }
37 }

前面说过,可以有多个catch块,去捕获不同的异常,真正执行的时候最多只进入一个catch块

  下面这个例子,定义了两种自定义的异常类型:

 1 多种异常 
 2 
 3 public class MyException extends Exception
 4 {
 5 
 6     public MyException()
 7     {
 8         super();
 9     }
10     
11     public MyException(String message)
12     {
13         super(message);
14     }
15 }
16 
17 
18 public class MyException2 extends Exception
19 {
20     public MyException2()
21     {
22         super();
23     }
24     public MyException2(String message)
25     {
26         super(message);
27     }
28 
29 }
30 
31 
32 public class ExceptionTest4
33 {
34 
35     public void method(String str) throws MyException, MyException2
36     {
37         if (null == str)
38         {
39             throw new MyException("传入的字符串参数不能为null!");
40         }
41         else if ("hello".equals(str))
42         {
43             throw new MyException2("传入的字符串不能为hello");
44         }
45         else
46         {
47             System.out.println(str);
48         }
49     }
50 
51     public static void main(String[] args)
52     {
53         // 异常处理方式2,采用try...catch语句
54         try
55         {
56             ExceptionTest4 test = new ExceptionTest4();
57             test.method(null);
58 
59         }
60         catch (MyException e)
61         {
62             System.out.println("进入到MyException catch块");
63             e.printStackTrace();
64         }
65         catch (MyException2 e)
66         {
67             System.out.println("进入到MyException2 catch块");
68             e.printStackTrace();
69         }
70         finally
71         {
72             System.out.println("程序处理完毕");
73         }
74 
75     }
76 }

我们可以使用多个catch块来捕获异常,这时需要将父类型的catch块放到子类型的catch块之后,这样才能保证后续的catch块可能被执行,否则子类型的catch块将永远无法到达,Java编译器会报错。

  如果异常类型是独立的,那么它们的前后顺序没有要求。

  如对上面的代码进行改动后,如下列出:

 1 多个catch语句块的顺序
 2 
 3 public class ExceptionTest4
 4 {
 5 
 6     public void method(String str) throws Exception // 也可以声明Exception,只要声明的可以涵盖所有抛出的异常即可
 7     {
 8         if (null == str)
 9         {
10             throw new MyException("传入的字符串参数不能为null!");
11         }
12         else if ("hello".equals(str))
13         {
14             throw new MyException2("传入的字符串不能为hello");
15         }
16         else
17         {
18             System.out.println(str);
19         }
20     }
21 
22     public static void main(String[] args)
23     {
24         // 异常处理方式2,采用try...catch语句
25         try
26         {
27             ExceptionTest4 test = new ExceptionTest4();
28             test.method(null);
29 
30         }
31         catch (MyException e)
32         {
33             System.out.println("进入到MyException catch块");
34             e.printStackTrace();
35         }
36         catch (MyException2 e)
37         {
38             System.out.println("进入到MyException2 catch块");
39             e.printStackTrace();
40         }
41         catch (Exception e)
42         {
43             //虽然需要加上,但是这块代码不会被执行,只是为了编译成功
44             System.out.println("进入到MyException catch块");
45             e.printStackTrace();
46             //如果去掉前面两个catch块或其中之一,则发生该异常时就会进入此catch块
47             //catch块的匹配是按照从上到下的顺序,所以这个块如果放在最前面就会捕获所有的异常,后面的块永远不会执行,这时候会提示编译错误
48         }
49         finally
50         {
51             System.out.println("程序处理完毕");
52         }
53 
54     }
55 }

面试常考题型

  try块中的退出语句

  虽然实际开发中不会遇到这样的情况,但是笔试面试时有关异常经常会问到如下情况:

 1 笔试面试题解析
 2 
 3 public class ExceptionTest5
 4 {
 5 
 6     public void method()
 7     {
 8         try
 9         {
10             System.out.println("进入到try块");
11             
12             //return;
13             //会先执行finally块再返回
14             
15             //虚拟机退出
16             //System.exit(0);
17             //不会执行finally块中的语句,直接退出
18         }
19         catch (Exception e)
20         {
21             System.out.println("异常发生了!");
22             
23         }
24         finally
25         {
26             System.out.println("进入到finally块");
27             
28         }
29         
30         System.out.println("后续代码");
31         
32     }
33     
34     public static void main(String[] args)
35     {
36         ExceptionTest5 test = new ExceptionTest5();
37         test.method();
38     }
39 }

在加上return语句前,程序输出:

    进入到try块

    进入到finally块

    后续代码

 

如果在try块中加入return语句:

  程序执行输出:

    进入到try块

    进入到finally块

 

说明try块中有return语句时,仍然会首先执行finally块中的语句,然后方法再返回。

  如果try块中存在System.exit(0);语句,那么就不会执行finally块中的代码,因为System.exit(0)会终止当前运行的Java虚拟机,程序会在虚拟机终止前结束执行。

Java基础(55):Exception类详解(转)

标签:

原文地址:http://www.cnblogs.com/lsgwr/p/5396545.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!