finally块中的语句要是也抛出异常怎么处理呢

qianshe223 2011-08-03 04:08:02
在数据库操作或者I/O读取文件时,通常使用try/catch块进行异常捕获,而将资源回收的代码,比如关闭数据库连接、关闭流等语句写在finally块中,但是发现使用InputStream时,close()函数也是要抛出异常的,感觉这是个比较麻烦的问题,于是翻阅Java核心技术求解,发现其中有个提示是建议采用独立的try/catch和try/finally语句组合,这样就可以捕获finally块中的异常。例如:


InputStream in = ...;

try{
try{
code may thorw exceptions
}finally{
in.close();
}
}catch(IOException e){
do some action
}


于是我按照例子进行了尝试,


public static void throwException(){
File f = null;
FileInputStream fis = null;

try{
try{
f = new File("abc");
// 这个文件是不存在的,所以应该抛出FileNotFoundException
fis = new FileInputStream(f);
fis.read();

}finally{
fis.close();

}
}catch(FileNotFoundException e){
System.out.println("file not found");
e.printStackTrace();

}catch(IOException e){
e.printStackTrace();
}

}

但是运行之后,却发现抛出的是NullPointerException,是finally中的fis.close()抛出的,没有抛出FileNotFoundException。
后来将finally中的fis.close()移到try语句块中,结果抛出了FileNotFoundException。
发现是finally块中的异常将try中的异常给冲掉了。
在Java核心技术书中,作者建议在finally块中尽量不要使用会抛出异常的资源回收语句,可是有些资源回收语句确实会抛出异常,这个到底该怎么办呢?

本人才疏学浅,见得不多,有问题就发到版上,希望版上高手给点解释!!!
...全文
2848 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
qianshe223 2011-08-03
  • 打赏
  • 举报
回复
谢谢大家的回复,我感觉我把问题搞复杂了


public static void throwException1(){
File f = null;
FileInputStream fis = null;

try{
f = new File("abc");
// 这个文件是不存在的,所以应该抛出FileNotFoundException
fis = new FileInputStream(f);
fis.read();

}catch(FileNotFoundException e){
System.out.println("file not found");
e.printStackTrace();

}catch(IOException e){
e.printStackTrace();
} finally{
try{ // 在finally对异常进行单独处理
if(fis!=null){ //非空才关闭
fis.close();
}
}catch(Exception e){
//异常处理,并写入日志
}

}
}


这样可以万无一失了吧,在finally中进行对fis.close()单独处理异常,并且检查其是否为null,是null则没必要关闭。只检查非空,不用try/catch是不行的
小绵羊 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 x19881216 的回复:]

Java code

public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream("c:/test.txt");
try {
OutputStream out = new FileOutputStr……
[/Quote]
commons io 包的写法,把异常抛出去或者在最外层处理一下就可以了。
小绵羊 2011-08-03
  • 打赏
  • 举报
回复

public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream("c:/test.txt");
try {
OutputStream out = new FileOutputStream("c:/test1.txt");
try {
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
out.flush();
} finally {
if (out != null) {
out.close();
}
}
} finally {
if (in != null) {
in.close();
}
}
}
qianshe223 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cbxjj 的回复:]

直接把close写到try里面
[/Quote]

2楼的建议和1楼差不多,而且多了日志,谢谢啊

我写的这个是引用的java核心技术里面的一种建议,一般情况我也不会这么写,之前以为这是一种比较好的解决办法,结果发现不是
qianshe223 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用楼主 qianshe223 的回复:]
在数据库操作或者I/O读取文件时,通常使用try/catch块进行异常捕获,而将资源回收的代码,比如关闭数据库连接、关闭流等语句写在finally块中,但是发现使用InputStream时,close()函数也是要抛出异常的,感觉这是个比较麻烦的问题,于是翻阅Java核心技术求解,发现其中有个提示是建议采用独立的try/catch和try/finally语句组合,这样就可以捕获finally块中的……
[/Quote]

那就是finally中再进行一次异常捕获呗,之前感觉在finally中进行异常捕获怪怪的
hxysjm520 2011-08-03
  • 打赏
  • 举报
回复
使用try-catch,最好先把程序流程弄清楚,要不你的try-catch会写的很乱!!!
hxysjm520 2011-08-03
  • 打赏
  • 举报
回复
public static void throwException(){
File f = null;
FileInputStream fis = null;

try{
try{
f = new File("abc");
// 这个文件是不存在的,所以应该抛出FileNotFoundException
fis = new FileInputStream(f);
fis.read();

}finally{
if(fis!=null){//非null,才需要close。若是null。都没占用资源,你还释放什么? fis.close();
}
}
}catch(FileNotFoundException e){
System.out.println("file not found");
e.printStackTrace();

}catch(IOException e){
e.printStackTrace();
}

}

再不斩 2011-08-03
  • 打赏
  • 举报
回复
finally里面写如果出异常的话,最后处理手段,如果处理手段有问题,可以在finally里面进行try/catch
,也可以抛给虚拟机进行处理。
我是这样觉得
hxysjm520 2011-08-03
  • 打赏
  • 举报
回复
一定都不麻烦,你没理清程序流程!
hxysjm520 2011-08-03
  • 打赏
  • 举报
回复
发现是finally块中的异常将try中的异常给冲掉了。
这句话说错了。
你没有把异常捕获和处理弄明白。
daijope 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 fly_m 的回复:]

finnlay中
if(xxx != null){
try{
is.close()//关闭资源
}catch(Exception e){
//忽略异常
}
}

以确保finnaly不会有异常发生
[/Quote]
好像一般 都这样处理。
meran 2011-08-03
  • 打赏
  • 举报
回复
写到日志到是不错
iis81365341 2011-08-03
  • 打赏
  • 举报
回复
finally中的异常在finally中捕获,不要在外层捕获。
ydj552110737 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 fly_m 的回复:]
finnlay中
if(xxx != null){
try{
is.close()//关闭资源
}catch(Exception e){
//忽略异常
}
}

以确保finnaly不会有异常发生
[/Quote]



晕啊 点错了 1楼正解~~~点错了 扔了个板砖 又给对我有用了一下 嘿嘿 正解 顶一下
wula0010 2011-08-03
  • 打赏
  • 举报
回复
在finally里如果还有异常,就不能再抛出了,捕获后处理,写到日志里。你的finally写的也不对:

public static void throwException(){
File f = null;
FileInputStream fis = null;

try{

f = new File("abc");
// 这个文件是不存在的,所以应该抛出FileNotFoundException
fis = new FileInputStream(f);
fis.read();
}catch(FileNotFoundException e){
System.out.println("file not found");
e.printStackTrace();

}catch(IOException e){
e.printStackTrace();
} finally{
try{
fis.close();
}catch(Exception e){
//异常处理,并写入日志
.......
}

}
}
剑神一笑 2011-08-03
  • 打赏
  • 举报
回复
直接把close写到try里面
Fly_m 2011-08-03
  • 打赏
  • 举报
回复
finnlay中
if(xxx != null){
try{
is.close()//关闭资源
}catch(Exception e){
//忽略异常
}
}

以确保finnaly不会有异常发生

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧