转:深化了解java反常处理机制ITeye - 亚美娱乐

转:深化了解java反常处理机制ITeye

2019-01-11 11:29:14 | 作者: 旭东 | 标签: 反常,处理,句子 | 浏览: 646

 

       关键词try后的一对大括号将一块或许发作反常的代码包起来,称为监控区域。Java办法在运转过程中呈现反常,则创立反常目标。将反常抛出监控区域之 外,由Java运转时体系企图寻觅匹配的catch子句以捕获反常。若有匹配的catch子句,则运转其反常处理代码,try-catch句子完毕。

 

       匹配的原则是:假如抛出的反常目标归于catch子句的反常类,或许归于该反常类的子类,则以为生成的反常目标与catch块捕获的反常类型相匹配。

 

例1  捕捉throw句子抛出的“除数为0”反常。

 

public class TestException { 
 public static void main(String[] args) { 
 int a = 6; 
 int b = 0; 
 try { // try监控区域 
 if (b == 0) throw new ArithmeticException(); // 经过throw句子抛出反常 
 System.out.println("a/b的值是:" + a / b); 
 catch (ArithmeticException e) { // catch捕捉反常 
 System.out.println("程序呈现反常,变量b不能为0。"); 
 System.out.println("程序正常完毕。"); 
} 

 

 

 

 

 

 

运转成果:程序呈现反常,变量b不能为0。

 

                    程序正常完毕。

 

        例1  在try监控区域经过if句子进行判别,当“除数为0”的过错条件成立时引发ArithmeticException反常,创立 ArithmeticException反常目标,并由throw句子将反常抛给Java运转时体系,由体系寻觅匹配的反常处理器catch并运转相应异 常处理代码,打印输出“程序呈现反常,变量b不能为0。”try-catch句子完毕,持续程序流程。

 

        事实上,“除数为0”等ArithmeticException,是RuntimException的子类。而运转时反常将由运转时体系主动抛出,不需求运用throw句子。

 

例2  捕捉运转时体系主动抛出“除数为0”引发的ArithmeticException反常。

 

 

 

 public static void main(String[] args) { 
 int a = 6; 
 int b = 0; 
 try { 
 System.out.println("a/b的值是:" + a / b); 
 } catch (ArithmeticException e) { 
 System.out.println("程序呈现反常,变量b不能为0。"); 
 System.out.println("程序正常完毕。"); 
 } 

 

运转成果:程序呈现反常,变量b不能为0。

 

                  程序正常完毕。

 

例2  中的句子:

 

System.out.println("a/b的值是:" + a/b);

 

      在运转中呈现“除数为0”过错,引发ArithmeticException反常。运转时体系创立反常目标并抛出监控区域,转而匹配适宜的反常处理器catch,并履行相应的反常处理代码。

 

      因为查看运转时反常的价值远大于捕捉反常所带来的好处,运转时反常不可查。Java编译器答应疏忽运转时反常,一个办法能够既不捕捉,也不声明抛出运转时反常。

 

例3  不捕捉、也不声明抛出运转时反常。

 

public class TestException { 
 public static void main(String[] args) { 
 int a, b; 
 a = 6; 
 b = 0; // 除数b 的值为0 
 System.out.println(a / b); 
} 

 

运转成果:

 

Exception in thread "main" java.lang.ArithmeticException: / by zero
at Test.TestException.main(TestException.java:8)

 

例4  程序或许存在除数为0反常和数组下标越界反常。

 

public class TestException { 
 public static void main(String[] args) { 
 int[] intArray = new int[3]; 
 try { 
 for (int i = 0; i = intArray.length; i++) { 
 intArray[i] = i; 
 System.out.println("intArray[" + i + "] = " + intArray[i]); 
 System.out.println("intArray[" + i + "]模 " + (i - 2) + "的值: " 
 + intArray[i] % (i - 2)); 
 } catch (ArrayIndexOutOfBoundsException e) { 
 System.out.println("intArray数组下标越界反常。"); 
 } catch (ArithmeticException e) { 
 System.out.println("除数为0反常。"); 
 System.out.println("程序正常完毕。"); 
}

 

运转成果:

intArray[0] = 0
intArray[0]模 -2的值:  0
intArray[1] = 1
intArray[1]模 -1的值:  0
intArray[2] = 2
除数为0反常。
程序正常完毕。

 

 

 

      例4  程序或许会呈现除数为0反常,还或许会呈现数组下标越界反常。程序运转过程中ArithmeticException反常类型是先行匹配的,因而履行相匹配的catch句子:

 

 catch (ArithmeticException e){ 
 System.out.println("除数为0反常。"); 
 } 

 

       需求留意的是,一旦某个catch捕获到匹配的反常类型,将进入反常处理代码。一经处理完毕,就意味着整个try-catch句子完毕。其他的catch子句不再有匹配和捕获反常类型的时机。

 

      Java经过反常类描绘反常类型,反常类的层次结构如图1所示。关于有多个catch子句的反常程序而言,应该尽量将捕获底层反常类的catch子 句放在前面,一起尽量将捕获相对高层的反常类的catch子句放在后边。不然,捕获底层反常类的catch子句将或许会被屏蔽。

 

      RuntimeException反常类包含运转时各种常见的反常,ArithmeticException类和ArrayIndexOutOfBoundsException类都是它的子类。因而,RuntimeException反常类的catch子句应该放在 最终边,不然或许会屏蔽这以后的特定反常处理或引起编译过错。

 

2. try-catch-finally句子

 

      try-catch句子还能够包含第三部分,便是finally子句。它表明不管是否呈现反常,都应当履行的内容。try-catch-finally句子的一般语法方式为:

 

 

 

 try { 
 // 或许会发作反常的程序代码 
 } catch (Type1 id1) { 
 // 捕获并处理try抛出的反常类型Type1 
 } catch (Type2 id2) { 
 // 捕获并处理try抛出的反常类型Type2 
 } finally { 
 // 不管是否发作反常,都将履行的句子块 
 } 

 

 

例5  带finally子句的反常处理程序。

 

 public class TestException { 
 public static void main(String args[]) { 
 int i = 0; 
 String greetings[] = { " Hello world !", " Hello World !! ", 
 " HELLO WORLD !!!" }; 
 while (i 4) { 
 try { 
 // 特别留意循环控制变量i的规划,防止形成无限循环 
 System.out.println(greetings[i++]); 
 } catch (ArrayIndexOutOfBoundsException e) { 
 System.out.println("数组下标越界反常"); 
 } finally { 
 System.out.println("--------------------------"); 
 } 

 

运转成果:

 

Hello world !
--------------------------
Hello World !!
--------------------------
HELLO WORLD !!!
--------------------------
数组下标越界反常
--------------------------

 

     在例5中,请特别留意try子句中句子块的规划,假如规划为如下,将会呈现死循环。假如规划为:

 

 try { 
 System.out.println (greetings[i]); i++; 
 } 

 

 

小结:

 

try 块:用于捕获反常。这以后可接零个或多个catch块,假如没有catch块,则有必要跟一个finally块。
catch 块:用于处理try捕获到的反常。
finally 块:不管是否捕获或处理反常,finally块里的句子都会被履行。当在try块或catch块中遇到return句子时,finally句子块将在办法回来之前被履行。在以下4种特别状况下,finally块不会被履行:
1)在finally句子块中发作了反常。
2)在前面的代码中用了System.exit()退出程序。
3)程序地点的线程逝世。
4)封闭CPU。

 


 

 

 

3. try-catch-finally 规矩(反常处理句子的语法规矩):

 

1)  有必要在 try 之后增加 catch 或 finally 块。try 块后可一起接 catch 和 finally 块,但至少有一个块。
2) 有必要遵从块次序:若代码一起运用 catch 和 finally 块,则有必要将 catch 块放在 try 块之后。
3) catch 块与相应的反常类的类型相关。
4) 一个 try 块或许有多个 catch 块。若如此,则履行第一个匹配块。即Java虚拟时机把实践抛出的反常目标顺次和各个catch代码块声明的反常类型匹配,假如反常目标为某个反常类型或其子类的实例,就履行这个catch代码块,不会再履行其他的 catch代码块
5) 可嵌套 try-catch-finally 结构。
6) 在 try-catch-finally 结构中,可从头抛出反常。
7) 除了下列状况,总将履行 finally 做为完毕:JVM 过早停止(调用 System.exit(int));在 finally 块中抛出一个未处理的反常;计算机断电、失火、或遭受病毒进犯。

 

4. try、catch、finally句子块的履行次序:

 

 

 

1)当try没有捕获到反常时:try句子块中的句子逐个被履行,程序将越过catch句子块,履行finally句子块和这以后的句子;

 

2)当try捕获到反常,catch句子块里没有处理此反常的状况:当try句子块里的某条句子呈现反常时,而没有处理此反常的catch句子块时,此反常将会抛给JVM处理,finally句子块里的句子仍是会被履行,但finally句子块后的句子不会被履行;

 

3)当try捕获到反常,catch句子块里有处理此反常的状况:在try句子块中是依照次序来履行的,当履行到某一条句子呈现反常时,程序将跳到catch句子块,并与catch句子块逐个匹配,找到与之对应的处理程序,其他的catch句子块将不会被履行,而try句子块中,呈现反常之后的句子也不会被履行,catch句子块履行完后,履行finally句子块里的句子,最终履行finally句子块后的句子;

 图示try、catch、finally句子块的履行:

 

                                          图2  图示try、catch、finally句子块的履行

 

4.2 抛出反常

 

      任何Java代码都能够抛出反常,如:自己编写的代码、来自Java开发环境包中代码,或许Java运转时体系。不管是谁,都能够经过Java的throw句子抛出反常。从办法中抛出的任何反常都有必要运用throws子句。

1. throws抛出反常
版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表亚美娱乐立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章