您的位置:首页 > 编程语言 > Java开发

java基础教程之异常

2009-08-30 14:03 253 查看
1. 异常(Exception)和错误(Error)
Java中的异常类定义了程序中遇到的轻微的错误条件。打开一个不存在的文件、网络连接中断、数组下标越界、正在加载的类文件丢失等都会引发异常。
Java中的错误类定义了程序中不能恢复的严重错误条件。如内存溢出、类文件格式错误等。这一类错误由Java运行系统处理,不需要我们去处理。
2. 异常处理
Java程序在执行过程中如出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出(throw)异常。
当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕获(catch)异常。捕获异常可通过try/catch/finally语句来实现。catch定义了如何处理出现的异常。一个try语句块后可以有多个catch语句。每个catch语句被称为一个异常处理器(Exception handler)。
如果Java运行时系统找不到可以捕获异常的方法,则运行时系统将终止,相应的Java程序也将退出。
处理异常有三种方式,分别是:
Ø 根本不处理异常
Ø 异常发生时处理(可由两种方式来实现)
Ø 在程序的另一个地方处理异常
现在来编写一个类,分别使用这三种方式来处理异常时,分别是什么情况。
2.1. 根本不处理异常:
public class Excep {
public int division(int a, int b){
return a/b;
}
}

class ExcepTest{
public static void main(String args[]){
Excep excep = new Excep();
excep.division(10, 0);
System.out.println("run success");
}
}
编译结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Excep.division(Excep.java:3)
at ExcepTest.main(Excep.java:10)
run success没有被打印出来,显然对异常不进行处理时系统被中途终止了。
2.2. 异常发生时处理(可由两种方式来实现):
2.2.1. 在方法中捕获可能出现的异常
public class Excep {
public int division(int a, int b){
try{
return a/b;
}catch(Exception e){
e.printStackTrace();
return 0;
}
}
}

class ExcepTest{
public static void main(String args[]){
Excep excep = new Excep();
excep.division(10, 0);
System.out.println("run success");
}
}
编译结果:
java.lang.ArithmeticException: / by zero
at Excep.division(Excep.java:4)
at ExcepTest.main(Excep.java:16)
run success
run success被打印出来,显然系统没有被中途终止了。
2.2.2. 在方法中抛出异常,用这种方法实现时,告诉用户调用的方法可能出现异常,如果这个异常对象不是RuntimeException类或RuntimeException类子类对象,必须抛出或捕获异常,否则出现异常。
public class Excep {
public int division(int a, int b) throws Exception{
return a/b;
}
}

class ExcepTest{
public static void main(String args[]){
Excep excep = new Excep();
try{
excep.division(10, 0);
}catch(Exception e){
e.printStackTrace();
}
System.out.println("run success");
}
}
编译结果:
java.lang.ArithmeticException: / by zero
at Excep.division(Excep.java:3)
at ExcepTest.main(Excep.java:11)
run success
run success被打印出来,显然系统没有被中途终止了。在这里异常被捕获,当然也可以选择抛出,让运行时系统来处理异常。
2.2.3. 在程序的另一个地方处理异常
public class Excep {
public int division(int a, int b){
return a/b;
}
}

class ExcepTest{
public static void main(String args[]){
Excep excep = new Excep();
try{
excep.division(10, 0);
}catch(Exception e){
e.printStackTrace();
}
System.out.println("run success");
}
}
编译结果:
java.lang.ArithmeticException: / by zero
at Excep.division(Excep.java:3)
at ExcepTest.main(Excep.java:11)
run success
run success被打印出来,显然系统没有被中途终止了。
在程序运行时,如果出现异常,那么就会产生异常类对象。如果没有捕获这一异常,那么系统将终止;如果捕获了这一异常,如果存在相应的捕获处理器,程序控制就会立刻转到它上面,同时异常类对象将作为参数传输过去。
3. RuntimeException异常类及其子类
对于RuntimeException异常类及其子类(如:ArithmeticException、NullPointException、IndexOutOfBoundsException等),可以选择不去捕获,这类异常由Java运行系统自动抛出并自动处理。也就是说,当类的一个方法抛出RuntimeException类及其子类异常对象时,调用这个方法时,可以不去捕获或抛出,让系统自动处理。例如:
public class Excep {
public int division(int a, int b) throws RuntimeException{
return a/b;
}
}

class ExcepTest{
public static void main(String args[]){
Excep excep = new Excep();
excep.division(10, 0);
System.out.println("run success");
}
}
编译时可以发现,编译器并没有强制要求捕获或抛出异常,可以编译。惹是方法抛出其它异常时,是无法编译的。
4. 自定义异常
在JAVA程序设计中,可根据需要自定义异常类。例如:
public class Excep {
public int division(int a, int b) throws Exception{
if(b<0)
throw new DivesorIsMinusException("除数不能为负数");
return a/b;

}
}

class ExcepTest{
public static void main(String args[]) throws Exception{
Excep excep = new Excep();
try{
excep.division(10, -1);
}catch(DivesorIsMinusException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}

System.out.println("run success");
}
}

class DivesorIsMinusException extends Exception{
DivesorIsMinusException(String strExc){
super(strExc);
}
}
编译结果:
DivesorIsMinusException: 除数不能为负数
at Excep.division(Excep.java:4)
at ExcepTest.main(Excep.java:14)
run success
5. 继承中关于异常的使用
如果父类中的方法抛出多个异常,则子类中的覆盖方法要么抛出相同的异常,要么抛出异常的子类,但不能抛出新的异常(注:构造方法除外)。例如:
public class Excep {
public int division(int a, int b) throws DivesorIsMinusException,ArithmeticException{
if(b<0)
throw new DivesorIsMinusException("除数不能为负数");
return a/b;
}
}

class DivesorIsMinusException extends Exception{
DivesorIsMinusException(String strExc){
super(strExc);
}
}
//childExcep类继承了Excep类
class childExcep extends Excep{
public int division(int a, int b) throws DivesorIsMinusException,ArithmeticException{
if(b<0)
throw new DivesorIsMinusException("除数不能为负数");
return a/b;
}
}

class ExcepTest{
public static int method(Excep excep){
try{
//因为Excep类的division()方法抛出两个异常,所以必须捕获或抛出,这里是捕获
return excep.division(10, 0);
}catch(DivesorIsMinusException e){
e.printStackTrace();
}catch(ArithmeticException e){
e.printStackTrace();
}
return 0;
}
public static void main(String args[]) throws Exception{
childExcep ce = new childExcep();
/*
* 根据多态的原理,可以把ce作为实参,如果子类childExcep抛出了其它
* 异常(如:FileNotFoundException),那么在method这个方法中就会
* 捕获不到这个DivesorIsMinusException或ArithmeticException异常
* 而使程序出错
*/
method(ce);
}
}
6. 抽象类、接口中的异常使用
我们可以在方法声明时,声明一个不会抛出的异常,当声明一个抛出的异常
时,Java编译器就会强迫方法的使用者对异常进行处理。这种方式通常应用于abstract base class和interface中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: