簡體   English   中英

流關閉模式的變種在Java中

[英]Variants of stream closing pattern in Java

在處理流時,我經常在Java文檔和其他人的代碼中看到以下模式:

FileInputStream fis = null;
try {
  fis = new FileInputStream("some.file");
  // do something useful with fis
} finally {
  if (fis != null) {
    fis.close();
  }
}

但我個人更喜歡不同的模式:

FileInputStream fis = new FileInputStream("some.file");
try {
  // do something useful with fis
} finally {
  fis.close();
}

我喜歡后者的簡潔,我認為這是正確的。 但我對正確性是對的嗎? 是否客觀上有理由偏愛另一個?

更新

即使我寫的例子幾乎是我在現實生活中編寫這樣的代碼,我的模式仍然更簡潔。 比較文檔方法:

public Object processFile(String fn) throws MyException {
  FileInputStream fis = null;
  try {
    fis = new FileInputStream(fn);
    return new Object(); // somehow derived from fis
  } catch (FileNotFoundException e) {
    throw new MySubExceptionForNotFound(e);
  } catch (IOException e) {
    throw new MySubExceptionForIoError(e);
  } finally {
    if (fis != null) {
      IOUtils.closeQuietly(fis);
    }
  }
}

用我的方法:

public Object processFile(String fn) throws MyException {
  try {
    FileInputStream fis = new FileInputStream(fn);
    try {
      return new Object(); // somehow derived from fis
    } finally {
      IOUtils.closeQuietly(fis);
    }
  } catch (FileNotFoundException e) {
    throw new MySubExceptionForNotFound(e);
  } catch (IOException e) {
    throw new MySubExceptionForIoError(e);
  }
}

我的一行更短! :d

有趣的是,如果你決定使用fis.close()而不是IOUtils.closeQuietly() ,我的代碼不會改變,而“官方”代碼將增長另外4行。

您發布的第二個示例不會嘗試/捕獲可能的錯誤... = new FileInputStream("..."); 如果加載文件失敗將返回。 在第一個示例中,您可以自動捕獲FileInputStream提供的錯誤。

我個人會選擇第一個更好的錯誤處理。

除非從方法中拋出異常,否則第二個示例不會編譯,因為FileNotFoundException是一個已檢查的異常。

Compile.java:5: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
        FileInputStream fis = new FileInputStream("some.file");

第一個示例也不編譯,因為您缺少相應的catch塊。 這是一個編譯示例。

import java.io.*;
public class Compile {

    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("some.file");
            // do something useful with fis

            if (fis != null) {
                fis.close();
            }
        }
        catch (FileNotFoundException fnf) {
        }
        catch (IOException ioe) {
        }
        finally {
        }
    }
}

使用try-with-resources

try (FileInputStream fis = new FileInputStream("some.file")) {
    // some code here
}

要回答推薦模式為何如此的問題,請考慮new FileInputStream(String)拋出一個您應該捕獲的已檢查異常的事實;

FileInputStream fis = null;
try {
    fis = new FileInputStream("somefile.txt");
} catch (FileNotFoundException e) {
    return false;
} finally {
    if (fis != null) {
        fis.close();
    }
}

允許您在與其他文件相關的異常相同的try / catch塊中處理它。 與以下相比,它具有簡潔和減少嵌套優勢:

try {
    FileInputStream fis = new FileInputStream("some.file");
    try {
        // do something useful with fis
    } finally {
        fis.close();
    }
} catch (FileNotFoundException e) {
    return false;
}

如果你沒有捕獲異常而只是讓它傳播,那么你的建議就更清晰 - 但是由於在IO庫中大量使用了檢查異常(包括來自類構造函數),捕獲和處理異常是很常見的,並且我認為只有一個模式用於教學目的而不是每次都向某人顯示略有不同的模式是有意義的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM