在程序运行的过程中,有时也会出现各种非正常的突发状况。针对这些非正常的突发状况,在Java中,引入了异常。以异常的形式对这些非正常的情况进行封装,通过异常处理机制对程序运行的时候发生的各种问题进行处理。
1. Java程序的执行过程中如出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出(throw)异常。
2. 当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕获(catch)异常。
3. 如果Java运行时系统找不到可以捕获异常的方法,则运行时系统将终止,相应的Java程序也将退出。
4. 程序员通常只能处理异常(Exception),而对错误(Error)无能为力。
在这里要区分一下错误(Error)与异常(Exception)。Error类称为错误类,它表示Java运行时产生的系统内部错误或资源耗尽的错误,是比较严重的,仅靠修改程序本身是不能恢复执行的。而Exception称为异常类,它表示程序本身可以处理的错误,在开发Java程序中进行的异常处理,都是针对Exception类及其子类。在Exception类的众多子类中有一个特殊的RuntimeException类,该类及其子类用于表示运行时的异常。除了此类,Exception类下所有其他的子类都用于表示编译时异常。
有时候发生了异常,程序立即终止,无法继续向下执行。为了解决这样的问题,jJava中提供了异常捕获,异常处理的try-catch-finally语句。举例说明:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Demo01
{
public static void main(String[] args)
{
FileInputStream fis = null;
try
{
fis = new FileInputStream("c:/a.txt");
int b;
b = fis.read();
while(b!= -1)
{
System.out.print((char)b);
b = fis.read();
}
//移到finally中去执行
//fis.close();
}
catch(FileNotFoundException e)
{
System.out.println("FileNotFoundException:"+e.getMessage());
}
catch(IOException e1)
{
System.out.println("IOException:"+e1.getMessage());
}
finally
{
try
{
fis.close();
}
catch(IOException ioe) //如果发生FileNotFoundException即没有文件被打开,则此时在finally从句中执行fis.close()也会出现异常
{
System.out.println("关闭文件出错!");
}
}
}
}
运行后的结果为:
首先要讲的是该语句的具体语法格式:
try{ // 可能会抛出特定异常的代码段 }catch(MyExceptionType myException){ // 如果myException 被抛出,则执行这段代码 }catch(Exception otherException){ } [finally{ //用于资源回收 //无条件执行的语句 }] |
2. catch 从句中引入一个可能出现的异常,一个try块可以和多个catch块配合以处理多个异常
3. 当try块内的任何代码抛出了由catch 子句指定的异常,则try代码块中的程序将会终止执行,并跳到相应的catch代码块中来执行。
4. 无论是否出现异常,程序最后都会执行finally代码块中的内容(只有在try从句或catch()从句中有System.exit()时,此时整个程序才会退出执行,finally从句将不再被执行)
Java中还有个方法叫throws。这个关键字对外声明该方法有可能发生的异常,这样调用者在调用方法时,就明确的知道该方法有异常,并且必须在程序中对异常进行处理。否则编译无法通过。在定义一个方法时候,如果并不能确定如何处理其中可能出现的异常,可以不在方法中对异常进行处理,而是将可能发生的异常让这个方法的调用者处理。如果一个异常没有在当前的try-catch模块中得到处理,则它会抛出到它的调用方法。如果一个异常回到了main()方法,仍没有得到处理,则程序会异常终止。
需要注意的是,捕获异常和抛出异常的方式,并不是排它的,它们可以结合起来使用:
method() throws XXXException
{ …
try{…}
catch(XXXExceptione)
{ …
throwe;
}
}
实例如下:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class BuPaoJieHe {
//定义一个方法readdFile()用于读取指定文件的内容,它可能会引起FileNotFoundException,IOException异常,但此处没有直接在这个
//方法中对它们进行处理,而是通过throws将这两个异常抛出,让这个方法的调用者处理
public void readFile() throws FileNotFoundException,IOException
{
FileInputStream fis = new FileInputStream("c:/a.txt");
int b;
b = fis.read();
while(b!= -1)
{
System.out.print((char)b);
b = fis.read();
}
fis.close();
}
public static void main(String[] args)
{
BuPaoJieHe te = new BuPaoJieHe();
try
{
te.readFile();
}
catch(FileNotFoundException e)
{
System.out.println("FileNotFoundException:"+e.getMessage());
}
catch(IOException e1)
{
System.out.println("IOException:"+e1.getMessage());
}
}
}
运行后的结果:
还有一点:
当子类中的方法覆盖父类中的方法时,可以不抛出异常。覆盖方法抛出的异常,可以抛出与被覆盖方法的相同的异常或者被覆盖方法的异常的子类异常。如果父类方法没有声明抛出异常,子类覆盖方法也不可以抛出”已检查”异常。