动手动脑6——异常处理

1.运行下面两端代码,观察结果:

第1段:

 1 import javax.swing.*;
 2 
 3 class AboutException {
 4    public static void main(String[] a) 
 5    {
 6       int i=1, j=0, k;
 7       //k=i/j;
 8     try
 9     {
10         k = i/j;    // Causes division-by-zero exception
11         //throw new Exception("Hello.Exception!");
12     }
13     catch (ArithmeticException e)
14     {
15         System.out.println("被0除.  "+ e.getMessage());
16     }
17     catch (Exception e)
18     {   if (e instanceof ArithmeticException)
19             System.out.println("被0除");
20         else
21         {  
22             System.out.println(e.getMessage());
23         }
24     }
25      finally
26      {
27              JOptionPane.showConfirmDialog(null,"OK");
28      }
29         
30   }
31 }

第2段:

 1 import javax.swing.*;
 2 
 3 class AboutException {
 4    public static void main(String[] a) 
 5    {
 6       int i=1, j=0, k;
 7       k=i/j;    //两端代码的区别就在这里
 8     try
 9     {
10         k = i/j;    // Causes division-by-zero exception
11         //throw new Exception("Hello.Exception!");
12     }
13     catch (ArithmeticException e)
14     {
15         System.out.println("被0除.  "+ e.getMessage());
16     }
17     catch (Exception e)
18     {   if (e instanceof ArithmeticException)
19             System.out.println("被0除");
20         else
21         {  
22             System.out.println(e.getMessage());
23         }
24     }
25      finally
26      {
27              JOptionPane.showConfirmDialog(null,"OK");
28      }
29         
30   }
31 }

两端代码区别就在一句,但是结果并不一样:

这是第1段代码:

这是第二段代码运行结果:

结果相差很大,原因很简单,代码1中,第一次出现的 k = i / j 这句被注释掉了,所以在第二次 k = i / j 才会抛出异常,而且这个异常有catch语句来捕捉,后面还有个finally语句来输出个消息面板。而如果不加注释,也就是第二段代码,第一次出现k = i / j就会发生异常(也就是不能除0那个),由于没有捕捉机制的设置,所以JVM会自动显示异常信息(当然并不是中文啦。。),并且会结束程序。

 

2.阅读下面的代码,分析结果:

 1 public class CatchWho { 
 2     public static void main(String[] args) { 
 3         try { 
 4                 try { 
 5                     throw new ArrayIndexOutOfBoundsException(); 
 6                 } 
 7                 catch(ArrayIndexOutOfBoundsException e) { 
 8                        System.out.println(  "ArrayIndexOutOfBoundsException" +  "/内层try-catch"); 
 9                 }
10  
11             throw new ArithmeticException(); 
12         } 
13         catch(ArithmeticException e) { 
14             System.out.println("发生ArithmeticException"); 
15         } 
16         catch(ArrayIndexOutOfBoundsException e) { 
17            System.out.println(  "ArrayIndexOutOfBoundsException" + "/外层try-catch"); 
18         } 
19     } 
20 }

由于实在内层发生的异常,内层的catch语句捕捉后直接处理掉

 

3.修改了上面的代码,分析下面的结果:

 1 public class CatchWho2 { 
 2     public static void main(String[] args) { 
 3         try {
 4                 try { 
 5                     throw new ArrayIndexOutOfBoundsException(); 
 6                 } 
 7                 catch(ArithmeticException e) { 
 8                     System.out.println( "ArrayIndexOutOfBoundsException" + "/内层try-catch"); 
 9                 }
10             throw new ArithmeticException(); 
11         } 
12         catch(ArithmeticException e) { 
13             System.out.println("发生ArithmeticException"); 
14         } 
15         catch(ArrayIndexOutOfBoundsException e) { 
16             System.out.println( "ArrayIndexOutOfBoundsException" + "/外层try-catch"); 
17         } 
18     } 
19 }

由于在内层的try中没有对ArrayIndexOutOfBoundsException这类异常进行处理的语句,所以这个异常会被抛出,而外层catch语句可以捕捉这类异常,所以最后输出结果会显示外层那一堆。

 

3.运行下面的代码,分析结果:

 1 public class EmbededFinally {
 2 
 3     
 4     public static void main(String args[]) {
 5         
 6         int result;
 7         
 8         try {
 9             
10             System.out.println("in Level 1");
11 
12            
13              try {
14                 
15                 System.out.println("in Level 2");
16   // result=100/0;  //Level 2
17                
18                  try {
19                    
20                      System.out.println("in Level 3");
21                       
22                      result=100/0;  //Level 3
23                 
24                 } 
25                 
26                 catch (Exception e) {
27                     
28                     System.out.println("Level 3:" + e.getClass().toString());
29                 
30                 }
31                 
32                 
33                 finally {
34                     
35                     System.out.println("In Level 3 finally");
36                 
37                 }
38                 
39                
40                 // result=100/0;  //Level 2
41 
42             
43                 }
44             
45             catch (Exception e) {
46                
47                  System.out.println("Level 2:" + e.getClass().toString());
48            
49              }
50              finally {
51                 
52                 System.out.println("In Level 2 finally");
53            
54              }
55              
56             // result = 100 / 0;  //level 1
57         
58         } 
59         
60         catch (Exception e) {
61             
62             System.out.println("Level 1:" + e.getClass().toString());
63         
64         }
65         
66         finally {
67            
68              System.out.println("In Level 1 finally");
69         
70         }
71     
72     }
73 
74 }

这个例子比较简单,整形除0抛出异常被捕捉,输出字符串形式的异常信息,该执行的finally块中的语句正常执行

 

4.finally语句一定会执行吗?当然不一定,如果catch捕捉异常之后执行了System.exit(0)这类结束程序的语句,finally自然不会执行。

比如下面这个例子:

 1 public class SystemExitAndFinally {
 2 
 3     
 4     public static void main(String[] args)
 5     {
 6         
 7         try{
 8 
 9             
10             System.out.println("in main");
11             
12             throw new Exception("Exception is thrown in main");
13 
14                     //System.exit(0);
15 
16         
17         }
18         
19         catch(Exception e)
20 
21             {
22             
23             System.out.println(e.getMessage());
24             
25             System.exit(0);
26         
27         }
28         
29         finally
30         
31         {
32             
33             System.out.println("in finally");
34         
35         }
36     
37     }
38 
39 
40 }

 

结果显然易见,in finally 是不会被输出的

 

5.关于跟踪异常的传播路径:

以下代码仅供参考:

 1 // UsingExceptions.java
 2 // Demonstrating the getMessage and printStackTrace
 3 // methods inherited into all exception classes.
 4 public class PrintExceptionStack {
 5    public static void main( String args[] )
 6    {
 7       try {
 8          method1();
 9       }
10       catch ( Exception e ) {
11          System.err.println( e.getMessage() + "\n" );
12          e.printStackTrace();
13       }
14    }
15 
16    public static void method1() throws Exception
17    {
18       method2();
19    }
20 
21    public static void method2() throws Exception
22    {
23       method3();
24    }
25 
26    public static void method3() throws Exception
27    {
28       throw new Exception( "Exception thrown in method3" );
29    }
30 }

运行结果:

 

 

 

6.一个抛出多个所谓“受控异常”的例子":

 1 import java.io.*;
 2 public class ThrowMultiExceptionsDemo { 
 3     public static void main(String[] args) 
 4         { 
 5       try { 
 6             throwsTest(); 
 7        } 
 8         catch(IOException e) { 
 9             System.out.println("捕捉异常"); 
10         }
11     }
12 
13     private static void throwsTest()  throws ArithmeticException,IOException { 
14         System.out.println("这只是一个测试"); 
15         // 程序处理过程假设发生异常
16         throw new IOException(); 
17         //throw new ArithmeticException(); 
18     } 
19 }

运行结果:

 

7.子类抛出受控异常的限制:一个子类的throws子句抛出的异常,不能是其基类同名方法抛出的异常对象的父类。

下面的这个例子可以说明这个问题:

 1 import java.io.*;
 2 
 3 
 4 public class OverrideThrows
 5 {
 6     public void test()throws IOException
 7     {
 8         FileInputStream fis = new FileInputStream("a.txt");
 9     }
10 }
11 class Sub extends OverrideThrows
12 {
13     //如果test方法声明抛出了比父类方法更大的异常,比如Exception
14     //则代码将无法编译……
15     public void test() throws FileNotFoundException
16     {
17             //...
18     }
19 }

注释上给出了具体说明。

 

8.最后我也来写一个简单的例子吧:

编写一个程序,此程序在运行时要求用户输入一个 整数,代表某门课的考试成绩,程序接着给出“不及格”、“及格”、“中”、“良”、“优”的结论。
要求程序必须具备足够的健壮性,不管用户输入什 么样的内容,都不会崩溃。

代码如下:

 1 import java.util.InputMismatchException;
 2 import java.util.Scanner;
 3 
 4 public class Test {
 5       @SuppressWarnings("resource")
 6     public static void main(String[]a) {
 7           int num = 0;
 8           Scanner input = new Scanner(System.in);
 9          
10               try {
11                   System.out.print("输入数学分数:");
12                   num = input.nextInt();      
13                   if(num<0||num>100)throw new NumberFormatException();
14               }
15               catch(NumberFormatException e) {
16                   //如果输入的是越界数字,直接抛出这个格式异常
17                   System.out.println("输入有误!");
18                   input.close();
19                   System.exit(-1);
20               }
21               catch(InputMismatchException e) {
22                   //如果输入的不是整形,而是double或者String等类型,会直接抛出这个异常
23                   System.out.println("输入有误!");
24                   input.close();
25                   System.exit(-1);
26               }
27           if(num<60)System.out.println("数学不及格");
28           else if(num>=60&&num<=69)System.out.println("数学及格");
29           else if(num>=70&&num<=79)System.out.println("数学中等");
30           else if(num>=80&&num<=89)System.out.println("数学良好");
31           else if(num>=90&&num<=99)System.out.println("数学优秀");
32           else System.out.println("数学满分");
33           input.close();
34       }
35 }

附上几次验证结果:

输入字符串(字符):

输入小数:

输入越界数字(小于0或者大于100):

 

 

最后小小的骄傲一下(P.S.:我数学确实还可以的说。。。):

 

 

----------------------------------------------------------------------------------------------

END

 

posted @ 2017-11-16 23:51  messi2017  阅读(162)  评论(0编辑  收藏  举报