异常处理

advertisement
Java程序设计
Java Programming
Spring, 2013
Contents




Why Exceptions?
What are Exceptions?
Handling Exceptions
Creating Exception Types
chapter 8 Exceptions
2/47
Why Exceptions(异常)?


During execution(执行), programs can run
into many kinds of errors;
What do we do when an error occurs?

Java uses exceptions to provide the error-handling
capabilities for its programs.
chapter 8 Exceptions
3/47
Exceptions (异常)
1.
Error Class

2.
Critical(严重的) error which is not acceptable in normal
application program.
Exception Class


Possible exception in normal application program
execution;
Possible to handle by programmer.
chapter 8 Exceptions
4/47
Exceptions (异常)

An exception is an event(事件) that occurs
during the execution of a program that
disrupts(使中断) the normal flow(流程) of
instructions(指令).
chapter 8 Exceptions
5/47
Exceptions (异常)



Treat exception as an object .
All exceptions are instances of a class
extended from Throwable class or its
subclass.
Generally, a programmer makes new
exception class to extend the Exception
class which is a subclass of Throwable
class.
chapter 8 Exceptions
6/47
Exception Class 继承关系
Object
Throwable
Error
Exception
RuntimeException
IOException
7
异常类的层次结构:
8
Classifying(分类) Java Exceptions
1. Unchecked Exceptions(非检查性异常)
• It is not required that these types of exceptions be
caught or declared on a method.
–
–
Runtime exceptions can be generated by methods or by the
JVM itself.
Errors are generated from deep within the JVM, and often
indicate a truly fatal state.
2. Checked Exceptions(检查性异常)
• Must either be caught by a method or declared in its
signature by placing exceptions in the method
signature.
9
Exception的分类

非检查性异常(unchecked exception):


以RuntimeException为代表的一些类,编译时发现不了,
只在能运行时才能发现。
检查性异常(checked exception):


一般程序中可预知的问题,其产生的异常可能会带来意想
不到的结果,因此Java编译器要求Java程序必须捕获或声
明所有的非运行时异常。
以IOException为代表的一些类。如果代码中存在检查性
异常,必须进行异常处理,否则编译不能通过。如:用户
连接数据库SQLException、FileNotFoundException。
chapter 8 Exceptions
10/47
Exception的分类

什么是Runtime Exception:


Java虚拟机在运行时生成的异常,如:被0除等系统错误、
数组下标超范围等,其产生比较频繁,处理麻烦,对程序
可读性和运行效率影响太大。因此由系统检测, 用户可不
做处理,系统将它们交给默认的异常处理程序(当然,必要
时,用户可对其处理)。
Java程序异常处理的原则是:
1.
2.
对于Error和RuntimeException,可以在程序中进行捕
获和处理,但不是必须的。
对于IOException及其他异常,必须在程序进行捕获和处
理。异常处理机制主要处理检查性异常。
chapter 8 Exceptions
11/47
Java Exception Type Hierarchy(层次)
virtual machine errors
12
系统异常类的层次结构:
chapter 8 Exceptions
13/47
Exception的分类
1.
2.
System-Defined Exception(系统定义的异常)
Programmer-Defined Exception(程序员自定
义异常)
chapter 8 Exceptions
14/47
System-Defined Exception
(系统定义的异常)



Raised implicitly by system because of
illegal execution of program;
Created by Java System automatically;
Exception extended from Error class and
RuntimeException class.
chapter 8 Exceptions
15/47
System-Defined Exception

IndexOutOfBoundsException:


ArrayStoreException:


When refer to object as a null pointer
SecurityException:


When using a negative size of array
NullPointerException:


When assign object of incorrect type to element of array
NegativeArraySizeException:


When beyond the bound of index in the object which use
index, such as array, string, and vector
When violate security. Caused by security manager
IllegalMonitorStateException:

When the thread which is not owner of monitor involves wait
or notify method
16/47
Programmer-Defined Exception
(程序员自定义异常)

Exceptions raised by programmer


Subclass of Exception class
Check by compiler whether the exception handler for
exception occurred exists or not
 If there is no handler, it is error.
chapter 8 Exceptions
17/47
User-defined Exceptions
(用户自定义异常)
Creating Exception Types:
class UserErr extends Exception
{
…
}
18/47
Example 1:
public class InsufficientFundsException extends Exception
{
private BankAccount excepbank;
private double excepAmount;
InsufficientFundsException(Bank ba, double dAmount)
{
excepbank=ba;
excepAmount=dAmount;
}
}
chapter 8 Exceptions
19/47
程序运行时发生异常,系统会抛出异常,如果程序中未处理
和捕获异常,异常抛出后程序运行中断。
public class Test {
public int[ ] bar() {
int a[ ] = new int[2];
for (int x = 0; x <= 2; x++) {
a[x] = 0; //抛出异常,程序中断
}
return a;
}
public static void main(String[] args) {
Test t = new Test();
t.bar();
//程序中断
System.out.println(“Method: foo”); //不被执行
}
}
系统给出的错误信息:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at exception.Test.bar(Test.java:7)
at exception.Test.main(Test.java:25)
20
Handling Exceptions(处理异常)
1.
Throwing an exception(抛出异常)

2.
When an error occurs within a method.

An exception object is created and handed off to
the runtime system(运行时系统). The runtime
system must find the code to handle the error.
Catching an exception(捕获异常)

The runtime system(运行时系统) searches for code to
handle the thrown exception. It can be in the same
method or in some method in the call(调用) stack(堆栈).
chapter 8 Exceptions
21/47
Keywords for Java Exceptions

try
Marks the start of a block associated with a set of exception handlers.

catch
If the block enclosed by the try generates an exception of this type, control
moves here; watch out for implicit subsumption.

finally
Always called when the try block concludes, and after any necessary catch
handler is complete.

throws
Describes the exceptions which can be raised by a method.

throw
Raises an exception to the first available handler in the call stack,
unwinding the stack along the way.
22/47
抛出异常– throw, throws
在一个方法的运行过程中,如果一个语句引起了
错误时,含有这个语句的方法就会创建一个包含
有关异常信息的异常对象,并将它传递给Java
运行时系统。
我们把生成异常对象并把它提交给运行时系统的
过程称为抛出(throw)异常。


1.
2.
throw — 在方法体中用throw手工抛出异常;
throws — 在方法头部间接抛出异常,即:申明
方法中可能抛出的异常。
23/47
1. 在方法体中用throw手工抛出
异常


throw抛出异常,可以是系统定义的异常,也可以是用户自
定义的异常。
语法格式:
throw new 异常类构造函数;
或
异常类名 对象名 =new 异常类构造函数;
throw 对象名;

例如:下面语句就抛出了一个IOException异常:
throw new IOException();
24/47
throw -Example
class ThrowStatement extends Exception {
public static void exp(int ptr) {
try{
if (ptr == 0)
throw new NullPointerException();
}
catch(NullPointerException e) { }
}
}
public static void main(String[] args) {
int i = 0;
ThrowStatement.exp(i);
}
25/47
2. throws—间接抛出异常(申明异常)



一个方法不处理它产生的异常,而是沿着调用层次向上传递,由
调用它的方法来处理这些异常,叫声明异常。
在定义方法时用throws关键字将方法中可能产生的异常间接抛
出。
若一个方法可能引发一个异常,但它自己却没有处理,则应该
声明异常,并让其调用者来处理这个异常,这时就需要用
throws关键字来指明方法中可能引发的所有异常。
类型 方法名(参数列表) throws 异常列表
{
//…代码
}
26/47
Example 1:
public class ExceptionTest{
void Proc(int sel) throws ArrayIndexOutOfBoundsException {
System.out.println(“In Situation" + sel );
if(sel==1) {
int iArray[ ]=new int[4];
iArray[10]=3;
//抛出异常
}
}
}
27
异常向上传递-Example
class ThrowStatement extends Exception {
public static void exp(int ptr) throws NullPointerException {
if (ptr == 0)
throw new NullPointerException();
}
}
public static void main(String[] args) {
int i = 0;
ThrowStatement.exp(i);
}
运行结果:
java.lang.NullPointerException
at ThrowStatement.exp(ThrowStatement.java:4)
at ThrowStatement.main(ThrowStatement.java:8)
28/47
Exceptions - throwing multiple(多个) exceptions
A Method can throw multiple exceptions.
Multiple exceptions are separated by commas after the
throws keyword:
public class MyClass {
public int computeFileSize()
throws IOException, ArithmeticException
{
...
}
}
29
Handling Exceptions

在一个方法中,对于可能抛出的异常,处理方式
有两种:
1.
2.
一个方法不处理它产生的异常,只在方法头部声明
使用throws抛出异常,使异常沿着调用层次向上
传递,由调用它的方法来处理这些异常。
用try-catch-finally语句对异常及时处理;
30/47
Handling Exceptions
public void replaceValue(String name, Object value)
throws NoSuchAttributeException {
Attr attr=find(name);
if(attr==null)
throw new NoSuchAttributeException(name);
}
attr.setValue(value);
try{
当replaceValue(…)
方法被调用时,调用者
需处理异常。
…
replaceValue(“att1”, “newValue”);
…
}catch(NoSuchAttributeException e){
e.printStackTrace();
}
31
处理异常语句try-catch-finally的基本格式为:
try {
//可能产生异常的代码;
} //不能有其它语句分隔
catch(异常类名 异常对象名) {
// 异常处理代码; //要处理的第一种异常
}
catch(异常类名 异常对象名) {
//异常处理代码; //要处理的第二种异常
}
…
finally {
//最终处理(缺省处理)
}
32
Exceptions –Syntax(语法)示例
try {
// Code which might throw an exception
// ...
} catch(FileNotFoundException x) {
// code to handle a FileNotFound exception
} catch(IOException x) {
// code to handle any other I/O exceptions
} catch(Exception x) {
// Code to catch any other type of exception
} finally {
// This code is ALWAYS executed whether an exception was thrown
// or not. A good place to put clean-up code. ie. close
// any open files, etc...
}
33
Handling Exceptions(处理异常)
•
•
try-catch 或 try-catch-finally .
Three statements help define how exceptions are
handled:
1. try
• identifies a block of statements within which an
exception might be thrown;
• A try statement can have multiple catch statements
associated with it.
2. catch
• must be associated with a try statement and identifies
a block of statements that can handle a particular type
of exception.
• The statements are executed if an exception of a
particular type occurs within the try block.
34
Handling Exceptions
3. finally (可选项)
– must be associated with a try statement and
identifies a block of statements that are executed
regardless of whether or not an error occurs
within the try block.
– Even if the try and catch block have a return
statement in them, finally will still run.
35
用try-catch-finally语句对异常及时处理-Example
class ThrowStatement extends Exception {
public static void exp(int ptr) {
try{
if (ptr == 0)
throw new NullPointerException();
}
catch(NullPointerException e){ }
}
}
public static void main(String[] args) {
int i = 0;
ThrowStatement.exp(i);
}
36
系统抛出异常后,捕获异常,运行finally块,程序运行继续。
public class Test {
public void foo() {
try {
int a[ ] = new int[2];
a[4] = 1;
/* causes a runtime exception due to the index */
System.out.println(“Method: foo”);//若异常发生,不执行
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("exception: " + e.getMessage());
e.printStackTrace();
}finally {
System.out.println("Finally block always execute!!!");
}
}
public static void main(String[] args) {
Test t = new Test();
t.foo();
System.out.println(“Excecution after Exception!!!”); //继续执行
}
}
37
运行结果:
exception: 4
java.lang.ArrayIndexOutOfBoundsException: 4
at exception.Test.foo(Test.java:8)
at exception.Test.main(Test.java:20)
Finally block always execute!!!
Excecution after Exception!!!
38
Exceptions -throwing multiple exceptions
public void method1() {
MyClass anObject = new MyClass();
try {
int theSize = anObject.computeFileSize();
} catch(ArithmeticException x) {
// ...
} catch(IOException x) {
// ...
}
}
39
Exceptions -catching multiple exceptions
Each try block can catch multiple exceptions.
Start with the most specific exceptions
FileNotFoundException is a subclass of IO Exception
It MUST appear before IOException in the catch list
public void method1() {
FileInputStream aFile;
try {
aFile = new FileInputStream(...);
int aChar = aFile.read();
//...
}catch(FileNotFoundException x) {
// ...
}catch(IOException x) {
// ...
}
}
40
Exception -The catch-all Handler
Since all Exception classes are a subclass of the Exception
class, a catch handler which catches "Exception" will catch
all exceptions.
It must be the last in the catch List.
public void method1(){
FileInputStream aFile;
try {
aFile = new FileInputStream(...);
int aChar = aFile.read();
//...
}
catch(IOException x){
// ...
}
catch(Exception x){
// Catch All Exceptions
}
}
41
User-defined Exceptions(用户自定义异常)的处理
用户自定义异常是检查性异常(checked exception),
必须用throw手工抛出并处理。
class UserErr extends Exception {
…
}
class UserClass {
…
UserErr x = new UserErr();
...
if (val < 1)
throw x;
}
42
//ThrowExample.java
class IllegalValueException
extends Exception
{ }
class UserTrial{
int val1,val2;
public UserTrial(int a,int b){
val1=a;
val2=b;
}
void show() throws IllegalValueException {
if ((val1<0) ||(val2>0))
throw new IllegalValueException();
System.out.println(“Value1=”+ val1);//不运行
System.out.println("Value2 ="+val2);
}
}
class ThrowExample{
public static void main(String args[ ]) {
UserTrial values=new UserTrial(-1,1);
try{
values.show();
}
catch (IllegalValueException e){
System.out.println("Illegal Values: Caught in main");
}
}
}
输出:
Illegal Values:
Caught in main
43
Exception Propagation(传递)



An exception can be handled at a higher level if it is not
appropriate to handle it where it occurs.
Exceptions propagate up through the method calling
hierarchy until they are caught and handled or until they
reach the level of the main method.
A try block that contains a call to a method in which an
exception is thrown can be used to catch that exception.
chapter 8 Exceptions
44/47
Exception Propagation (传递)


Exception Propagation Order
 If there is no catch block to deal with the
exception, it is propagated to calling
method(调用方法)
All executions are ignored until finding the
exception handler
[Propagate.java]
chapter 8 Exceptions
45/47
Exception Propagation
public class Propagate {
void orange() {
ArithmeticException Occurred
int m = 25, i = 0;
i = m / i;
}
void apple() {
orange();
}
public static void main(String[] args) {
Propagate p = new Propagate();
p.apple();
}
Output by Default Exception
}
Handler
java.lang.ArithmeticException:
/ by zero
at Propagate.orange(Propagate.java:4)
at Propagate.apple(Propagate.java:8)
at Propagate.main(Propagate.java:11)
46
小结:异常处理机制
1. 在方法声明首部用throws声明抛出异常:异常处
理机制采用谁调用,谁就负责处理被调用方法抛出
的异常。
2. 在方法体中用throw手工抛出异常。
3. 使用try…catch…finally结构对异常进行捕获和处
理。
47
Download