在数据库操作或者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块中尽量不要使用会抛出异常的资源回收语句,可是有些资源回收语句确实会抛出异常,这个到底该怎么办呢?本人才疏学浅,见得不多,有问题就发到版上,希望版上高手给点解释!!!
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块中尽量不要使用会抛出异常的资源回收语句,可是有些资源回收语句确实会抛出异常,这个到底该怎么办呢?本人才疏学浅,见得不多,有问题就发到版上,希望版上高手给点解释!!!
if(xxx != null){
try{
is.close()//关闭资源
}catch(Exception e){
//忽略异常
}
}以确保finnaly不会有异常发生
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){
//异常处理,并写入日志
.......
}
}
}
这句话说错了。
你没有把异常捕获和处理弄明白。
,也可以抛给虚拟机进行处理。
我是这样觉得
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();
}
}
那就是finally中再进行一次异常捕获呗,之前感觉在finally中进行异常捕获怪怪的
2楼的建议和1楼差不多,而且多了日志,谢谢啊我写的这个是引用的java核心技术里面的一种建议,一般情况我也不会这么写,之前以为这是一种比较好的解决办法,结果发现不是
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();
}
}
}
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是不行的