2011-01-18 10 views
10

これはコードスタイルの質問です。オープンストリームのJavaコードスタイルtry/finallyブロック

InputStream in = null; 
try { 
    in = acquireStream(); 
    ... 
} finally { 
    if (in != null) in.close(); 
} 

注初期化がヌルとfinallyブロックにヌルをチェックする:私はいくつかexamples from Oracleストリームは以下のように閉じていることを確認含む多くのコード例に気づきます。

私はこのようなコードを記述する傾向がある:どちらかのアプローチには長所や短所が

InputStream in = acquireStream(); 
try { 
    ... 
} finally { 
    in.close(); 
} 

ありますか?私はヌルチェックが必要ないので私のスタイルが好きです。可能であれば、私はnullを避けたい。しかし、Oracleのスタイルはオンラインの例では非常に一般的なので、私には隠れたエラーがあるのだろうかと思っています。

は私が tryブロック外のリソースを取得し、その後はnullチェックなし finallyでそれを閉鎖する傾向があるなど、 InputStreamOutputStreamjava.sql.Connectionjava.sql.PreparedStatementに同じ質問をします。文体の違い以外に紛失しているものはありますか?

ありがとうございました。

答えて

3

通常はあなたが持っているものはtrycatchfinallyです。その場合、trycatchの中にacquireStream()で発生したエラーをキャプチャできるので、標準的なSUNアプローチを使用すると便利です。

0

acquireStream()がnullを返した場合、ストリームを最後にブロックしようとするとNPEが返され、キャッチされません。

0

私は最初の方が好きです。一部のI/O演算子は、 の条件またはその他のtry/catch内にあることを要求します。また、マニュアルに記載されていないとしても、操作は予期せずnullを返すことがあります。

3

aquireStream()は、任意のチェック例外をスローし、私はそれを処理するために計画していた場合、私は

InputStream in = null; 
try { 
    in = acquireStream(); 
    ... 
} finally { 
    if (in != null) in.close(); 
} 

を使用します。エルス

、私はNPEにこの

InputStream in = acquireStream(); 
try { 
    ... 
} finally { 
    in.close(); 
} 

を使用します。

私はむしろ、NPEが伝播するようにしましょうと任意の実行時例外を処理しません。

2

tryブロック内のストリームを取得する方が安全だと思います。クロージングのための別のオプションがあります

- あなたは次の操作を行うことができます代わりにnullをチェックする:

finally { 
    IOUtils.closeQuietly(in); 
} 

これ行い、これを行うためにはApache Commonsの-IOを必要とするが、それはあなたのためのヌルチェックを行います。これを行うには、書道的にもいい方法です。

+0

参照:http://commons.apache.org/io/api-release/org/apache/commons/io/IOUtils.html#closeQuietly(java.io.InputStream) – Jon

0

I通常do this

InputStream in = null; 
try { 
    in = acquire(); 
    ... 
} finally { 
    if(in != null) try { 
     in.close(); 
    } catch(IOException ioe) { 
     // ignore exception while closing 
    } 
} 

リソースを閉じ、例外がスローされる可能性がありますが、その場合、あなたは余分なのtry/catchが必要になりますが、私は無視するための時間のほとんどは、それは大丈夫です(私は結局それを閉じている)しかし、これは唯一の私は中括弧なしで使用する場所です。

私はこのことをHuckstercodeからずっと前に見ました。

+0

実際にコンパイルされます(宣言された、この場合には起こりそうにない場合は例外)。 –

+0

'finally'節に明確に割り当てられていない' in'の参照です。 –

+0

@トム、あなたは絶対に正しいです。私は次のように混乱しました: 'オブジェクトo; if(cond){o = something; } else {o =何か; } 'イディオム。一定! – OscarRyz

5

答えは、いいえ、あなたのやり方に隠れたエラーはありません。純粋にスタイルのものです。 私は通常、try catch catch finallyブロックを使用せず、catchブロックを試してfinallyブロックを試します。

彼らはこのように見える終わる傾向にある:

try { 
    InputStream in = acquireStream(); 
    try { 
     ... 
    } finally { 
     in.close(); 
    } 
} catch (IOException e) { 
    ... handle exception 
} 

ブロック最終的試みでacquireStreamを()入れする理由はありません。 inが有効なストリームに割り当てられていない場合、決してそれを閉じることはできません。明示的なヌルチェックはまったく必要ありません。さらに、メイン処理ブロック内の例外とは別にclose()で例外を処理することは稀です。

+0

私はこの解決策が好きです – wutzebaer

8

してみてください、最終的にはCloseableリソースに関して、ブロック書き込みに非常に良くな方法がありますJavaの7ので。

try (init resources) { 
    ... 
} 

を、コードのブロックが終了した後、彼らはautomcatically閉鎖されます。

今、あなたは、このように、tryキーワードの後の括弧内にリソースを作成することができます。 finallyブロックのストリームを閉じる必要はありません。

try (
    ZipFile zf = new ZipFile(zipFileName); 
    BufferedWriter writer = Files.newBufferedWriter(outputFilePath, charset); 
) { 
    // Enumerate each entry 
    for (Enumeration entries = zf.entries(); entries.hasMoreElements();) { 
     // Get the entry name and write it to the output file 
     String newLine = System.getProperty("line.separator"); 
     String zipEntryName = ((java.util.zip.ZipEntry)entries.nextElement()).getName() + newLine; 
     writer.write(zipEntryName, 0, zipEntryName.length()); 
    } 
} 

そしてforループが行われた後、リソースがクローズされます!

+0

ありがとう!クローズ可能なオブジェクトを処理することをお勧めします。 –