在使用IO流时,会遇到很多方法会抛出异常。对于这些异常,我们不应该简单的将其抛出,而是应该进行一些处理。
public class Test {
public static void main(String[] args) {
//创建一个字符流对象,用于将内容写入硬盘的文件
FileWriter fw = new FileWriter("c:\\demo.txt");
//写一个字符串
fw.write("java");
//关闭资源
fw.close();
}
}
这个简单的程序中的三行代码用于将一句字符串写入文件中然后关闭资源。但是这三句话都会抛出异常。所以将这三行代码放入try-catch 中。因为这三行代码有紧密的联系,所以放入同一个try中。
public class Test {
public static void main(String[] args) {
try{
//创建一个字符流对象,用于将内容写入硬盘的文件
FileWriter fw = new FileWriter("c:\\demo.txt");
//写一个字符串
fw.write("java");
//关闭资源
fw.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
编译通过。乍看上去似乎没有问题,但是细细一想就会发现:如果前两行代码有一行出现异常,那么后面的关闭资源就不会执行,而是直接运行catch中的处理代码,这样,资源不是关闭释放。所以要将关闭资源的代码放到finally中。
public class Test {
public static void main(String[] args) {
try{
//创建一个字符流对象,用于将内容写入硬盘的文件
FileWriter fw = new FileWriter("c:\\demo.txt");
//写一个字符串
fw.write("java");
}catch(IOException e){
e.printStackTrace();
}finally{
//关闭资源
fw.close();
}
}
}
将程序改为如上,这时fw.close()这句代码编译失败。因为fw定义在try中,是个局部变量,在finally中不可以引用到try中的局部变量。所以要提升fw的访问范围。但是又不能将fw的整句代码放到try外面,因为FileWriter的构造器也会抛出异常。所以将fw的定义放在try外面而将初始化放在try中。
public class Test {
public static void main(String[] args) {
//将fw的定义放在try外面
FileWriter fw = null;
try{
//将fw的初始化放在try中
fw = new FileWriter("c:\\demo.txt");
//写一个字符串
fw.write("java");
}catch(IOException e){
e.printStackTrace();
}finally{
//关闭资源
fw.close();
}
}
}
这样,再次编译,fw.close还是编译失败。因为close方法也会出现异常,所以要在finally中使用try-catch
public class Test {
public static void main(String[] args) {
//将fw的定义放在try外面
FileWriter fw = null;
try{
//将fw的初始化放在try中
fw = new FileWriter("c:\\demo.txt");
//写一个字符串
fw.write("java");
}catch(IOException e){
e.printStackTrace();
}finally{
try {
//关闭资源
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
再次编译,不会出现编译失败,而且也可以正常运行。但是还需仔细分析:如果在fw的初始化出现异常,比如文件的位置保存在不存在的k盘,那么初始化失败,抛出异常。这时,finally是一定执行的代码,即close方法一定会执行,但是fw并没有初始化,关闭动作肯定失败。所以要在关闭的前面加上一个判断,判断fw是否初始化。
最终我们将代码修改如下:
public class Test {
public static void main(String[] args) {
//将fw的定义放在try外面
FileWriter fw = null;
try{
//将fw的初始化放在try中
fw = new FileWriter("c:\\demo.txt");
//写一个字符串
fw.write("java");
}catch(IOException e){
e.printStackTrace();
}finally{
try {
//判断fw是否初始化过
if(fw != null)
//关闭资源
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
当然,在实际开发中还要增加catch中的实际异常处理代码而不是简单的打印。