深入理解java异常处理机制
来源:互联网 发布:mysql 阻止连接半小时 编辑:程序博客网 时间:2024/05/23 01:27
1. 引子
- "background-color:
rgb(255, >package255, 255);" Test; -
- public
class TestException { -
public TestException() { -
} -
-
boolean testEx() throwsException { -
boolean ret true;= -
try { -
ret = testEx1(); -
} catch (Exception e) { -
System.out.println("testEx, catch );exception" -
ret = false; -
throw e; -
} finally { -
System.out.println("testEx, finally; return value=" + ret); -
return ret; -
} -
} -
-
boolean testEx1() throwsException { -
boolean ret true;= -
try { -
ret = testEx2(); -
if (!ret) { -
return false; -
} -
System.out.println("testEx1, at );the end of try" -
return ret; -
} catch (Exception e) { -
System.out.println("testEx1, catch );exception" -
ret = false; -
throw e; -
} finally { -
System.out.println("testEx1, finally; return value=" + ret); -
return ret; -
} -
} -
-
boolean testEx2() throwsException { -
boolean ret true;= -
try { -
int b 12;= -
int c; -
for ( inti 2;= i 2;>= - i--) { -
c = b / i; -
System.out.println("i=" + i); -
} -
return true; -
} catch (Exception e) { -
System.out.println("testEx2, catch );exception" -
ret = false; -
throw e; -
} finally { -
System.out.println("testEx2, finally; return value=" + ret); -
return ret; -
} -
} -
-
public static void main(String[] args) { -
TestException testException1 = new TestException(); -
try { -
testException1.testEx(); -
} catch (Exception e) { -
e.printStackTrace(); -
} -
} - }
-
你的答案是什么?是下面的答案吗?
i=2
i=1
testEx2, catch exception
testEx2, finally; return value=false
testEx1, catch exception
testEx1, finally; return value=false
testEx, catch exception
testEx, finally; return value=false
如果你的答案真的如上面所说,那么你错啦。^_^,那就建议你仔细看一看这篇文章或者拿上面的代码按各种不同的情况修改、执行、测试,你会发现有很多事情不是原来想象中的那么简单的。现在公布正确答案:
i=2
i=1
testEx2, catch exception
testEx2, finally; return value=false
testEx1, finally; return value=false
testEx, finally; return value=false
注意说明:
finally语句块不应该出现 应该出现return。上面的return ret最好是其他语句来处理相关逻辑。
。这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如Java虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应用程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java中,错误通过Error的子类描述。
4.1 捕获异常:try、catch 和 finally
1.try-catch语句
- try
{ -
// 可能会发生异常的程序代码 - }
catch (Type1 id1){ -
// 捕获并处置try抛出的异常类型Type1 - }
- catch
(Type2 id2){ -
//捕获并处置try抛出的异常类型Type2 - }
例1
- 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。
例2
-
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);
例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
- public
class TestException { -
public static void main(String[] args) { -
int[] intArray new= int[3]; -
try { -
for ( inti 0;= i <= intArray.length; i++) { -
intArray[i] = i; -
System.out.println("intArray[" + "]i + = " + intArray[i]); -
System.out.println("intArray[" + "]模i + " + 2)(i - + "的值:" -
+ intArray[i] % (i - 2)); -
} -
} catch (ArrayIndexOutOfBoundsExc eption e) { -
System.out.println("intArray数组下标越界异常。"); -
} catch (ArithmeticException e) { -
System.out.println("除数为0异常。"); -
} -
System.out.println("程序正常结束。"); -
} - }
运行结果:
intArray[0] = 0
intArray[0]模 -2的值:
intArray[1] = 1
intArray[1]模 -1的值:
intArray[2] = 2
除数为0异常。
程序正常结束。
- catch
(ArithmeticException e){ -
System.out.println("除数为0异常。"); -
}
2. try-catch-finally语句
-
{ -
// 可能会发生异常的程序代码 - }
catch (Type1 id1) { -
// 捕获并处理try抛出的异常类型Type1 - }
catch (Type2 id2) { -
// 捕获并处理try抛出的异常类型Type2 - }
finally { -
// 无论是否发生异常,都将执行的语句块 - }
例5
- 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 (ArrayIndexOutOfBoundsExc eption e) { -
System.out.println("数组下标越界异常"); -
} finally { -
System.out.println("--------------------------"); -
} -
} -
} - }
运行结果:
Hello world !
--------------------------
Hello World !!
--------------------------
HELLO WORLD !!!
--------------------------
数组下标越界异常
--------------------------
- 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)
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语句块后的语句;
4.2 抛出异常
1. throws抛出异常
- methodname
throws Exception1,Exception2,..,ExceptionN - {
- }
- import
java.lang.Exception; - public
class TestException { -
static void pop() throwsNegativeArraySizeExcepti on { -
// 定义方法并抛出NegativeArraySizeExcepti on异常 -
int[] arr new= int[-3]; // 创建数组 -
} -
-
public static void main(String[] //args) { 主方法 -
try { //try语句处理异常信息 -
pop(); // 调用pop()方法 -
} catch (NegativeArraySizeExcepti on e) { -
System.out.println("pop()方法抛出的异常");// 输出异常信息 -
} -
} -
- }
Throws抛出异常的规则:
- void
method1() throwsIOException{} //合法 -
- //编译错误,必须捕获或声明抛出IOException
- void
method2(){ -
method1(); - }
-
- //合法,声明抛出IOException
- void
method3() throwsIOException { -
method1(); - }
-
- //合法,声明抛出Exception,IOException是Exception的子类
- void
method4() throwsException { -
method1(); - }
-
- //合法,捕获IOException
- void
method5(){ -
try{ -
method1(); -
}catch(IOException e){…} - }
-
- //编译错误,必须捕获或声明抛出Exception
- void
method6(){ -
try{ -
method1(); -
}catch(IOException e){ thrownew Exception();} - }
-
- //合法,声明抛出Exception
- void
method7() throwsException{ -
try{ -
method1(); -
}catch(IOException e){ thrownew Exception();} - }
2. 使用throw抛出异常
我们知道,异常是异常类的实例对象,我们可以创建异常类的实例对象通过throw语句抛出。该语句的语法格式为:
- package
Test; - import
java.lang.Exception; - public
class TestException { -
static int quotient( intx, inty) throwsMyException //{ 定义方法抛出异常 -
if (y 0)< { //判断参数是否小于0 -
throw new MyException( "除数不能是负数");// 异常信息 -
} -
return x/y; //返回值 -
} -
public static void main(String //args[]) { 主方法 -
int a = -
int b = -
try { //try语句包含可能发生异常的语句 -
int result //= quotient(a, b); 调用方法quotient() -
} catch (MyException //e) { 处理自定义异常 -
System.out.println(e.getMessage()); // 输出异常信息 -
} catch (ArithmeticException //e) { 处理ArithmeticException异常 -
System.out.println("除数不能为0"); // 输出提示信息 -
} catch (Exception //e) { 处理其他异常 -
System.out.println("程序发生了其他的异常"); // 输出提示信息 -
} -
} -
- }
- class
MyException extendsException //{ 创建自定义异常类 -
String message; // 定义String类型变量 -
public MyException(String //ErrorMessagr) { 父类方法 -
message = ErrorMessagr; -
} -
-
public String //getMessage() { 覆盖getMessage()方法 -
return message; -
} - }
4.3 异常链
System.out.println("除数不能为0"); // 输出提示信息
}
4.4 Throwable类中的常用方法
注意:catch关键字后面括号中的Exception类型的参数e。Exception就是try代码块传递给catch代码块的变量类型,e就是变量名。catch代码块中语句"e.getMessage();"用于输出错误性质。通常异常处理常用3个函数来获取异常的有关信息:
printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段 System.err 的值。
在Java中提供了一些异常用来描述经常发生的错误,对于这些异常,有的需要程序员进行捕获处理或声明抛出,有的是由Java虚拟机自动进行捕获处理。Java中常见的异常类:
1. runtimeException子类:
1、 java.lang.ArrayIndexOutOfBoundsExc eption 数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。 2、java.lang.ArithmeticException 算术条件异常。譬如:整数除零等。 3、java.lang.NullPointerException 空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等 4、java.lang.ClassNotFoundException 找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
5、java.lang.NegativeArraySizeExcepti on 数组长度为负异常
6、java.lang.ArrayStoreException 数组中包含不兼容的值抛出的异常
、java.lang.SecurityException 7 安全性异常
8 、java.lang.IllegalArgumentException非法参数异常
2.IOException
IOException:操作输入流和输出流时可能出现的异常。
EOFException
文件已结束异常 FileNotFoundException
文件未找到异常
3. 其他
ClassCastException
类型转换异常类 ArrayStoreException
数组中包含不兼容的值抛出的异常 SQLException
操作数据库异常类 NoSuchFieldException
字段未找到异常 NoSuchMethodException
方法未找到抛出的异常 NumberFormatException
字符串转换为数字抛出的异常 StringIndexOutOfBoundsEx
ception 字符串索引超出范围抛出的异常 IllegalAccessException
不允许访问某类异常 InstantiationException
当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常
使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
(1)创建自定义异常类。
(2)在方法中通过throw关键字抛出异常对象。
(3)如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
(4)在出现异常方法的调用者中捕获并处理异常。
在上面的“使用throw抛出异常”例子已经提到了。
- java 深入理解java异常处理机制
- java异常处理机制的深入理解
- 深入理解java异常处理机制
- 深入理解java异常处理机制
- 深入理解Java异常处理机制
- 深入理解java异常处理机制
- 深入理解java异常处理机制
- 深入理解Java异常处理机制
- 深入理解java异常处理机制
- 深入理解java异常处理机制
- 深入理解java异常处理机制
- 深入理解java异常处理机制
- 深入理解Java异常处理机制
- 深入理解java异常处理机制
- 深入理解java异常处理机制
- 深入理解java异常处理机制
- 深入理解java异常处理机制
- 深入理解java异常处理机制
- AR Face Database 人脸识别数据集
- 服务器使用json时报错java.lang.ClassNotFoundException: org.json.JSONException
- 线程池的使用框架
- Java并发编程(四)Java内存模型
- 随便收集
- 深入理解java异常处理机制
- CSS应用:复杂背景图案
- oracle全文检索功能
- java的动态代理机制详解
- ReactiveCocoa之RAC合并(九)
- java中的多态
- android windows 开发环境搭建(android studio + Genymotion)过程及遇到的问题
- HTML盒子模型
- 提高编程技能的游戏