2011-01-18 4 views
10

이것은 코드 스타일 질문입니다. 초기화가 null에 finally 블록에 null을 확인하기 위해개방형 스트림 try/finally 블록 용 Java 코드 스타일

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

참고 : 좀 examples from Oracle이 스트림은 다음과 같은 방식으로 폐쇄되어 있는지 확인을 포함하여 많은 예제 코드를 확인할 수 있습니다.

나는 다음과 같은 코드를 작성하는 경향이 중 접근 방식의 장점 또는 단점은

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

이 있습니까? 나는 널 수표가 필요 없기 때문에 내 스타일을 좋아한다. 나는 가능한 한 null을 피하고 싶다. 하지만 오라클 스타일은 온라인 예제에서 흔히 볼 수있는 것이므로 숨겨진 오류가 있는지 궁금합니다.

나는 내가 try 블록 외부 리소스를 인수 한 후 NULL 체크하지 않고 finally에 닫습니다 경향 등 InputStream, OutputStream, java.sql.Connection, java.sql.PreparedStatement에 대해 같은 질문을. 문체상의 차이점 이외에 내가 놓친 것이 있습니까?

감사합니다.

답변

3

일반적으로 당신이 무엇을, finallycatchtry입니다. 이 경우 acquireStream()에 발생한 오류를 try, catch 안에 캡처 할 수 있으므로 표준 SUN 방식을 사용하는 것이 좋습니다.

0

acquireStream()이 null을 반환하면 finally 블록에서 스트림을 닫으려고 할 때 NPE가 표시되고 catch되지 않습니다.

0

나는 첫 번째를 선호한다. 일부 I/O 운영자는 에 대한 try/catch 안의 일부 조건을 요구합니다. 또한 설명서에없는 경우에도 작업은 항상 예기치 않게 null을 반환 할 수 있습니다 ( ). aquireStream() 어떤 예외를 확인하고 내가 그것을 처리 할 계획입니다 발생하는 경우

3

나는

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); 
} 

이 수행이 작업을 수행 할 아파치 코 몬즈 - 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 
    } 
} 

자원을 종료, 예외가 발생 될 수 있지만,이 경우 당신은 여분의 시도/캐치가 필요합니다,하지만 나를 무시하는 시간의 대부분은 괜찮아요 그것 (나는 결국 그것을 닫고있다.) 그러나 이것은 중괄호없이 if를 사용하는 유일한 장소이다.

나는 이것을 Huckstercode에서 오래 전에 보았다.

+0

실제로 컴파일됩니다 (선언 된 ,이 경우는있을 수 없다면 예외). –

+0

'finally' 절에서 명확하게 지정되지 않은'in'을 참조합니다. –

+0

@ 톰, 당신은 절대적으로 맞습니다. 나는 다음과 혼동을 느낀다 :'Object o; if (cond) {o = something; } else {o = 무언가; }'숙어. 결정된! – OscarRyz

5

답은 아니오입니다. 귀하의 방식대로 숨겨진 오류가 없습니다. 그것은 순전히 스타일의 것입니다. 나는 일반적으로 finally 블록을 try try 해 본 적이 없으며 catch 블록을 시도하고 finally 블록을 시도한다.

그들은이처럼 보이는 결국 경향이 finally 블록은 try에 acquireStream()를 넣어 이유가

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

없습니다. in이 유효한 스트림에 할당되지 않으면 결코 닫을 수 없습니다. 명시적인 널 (NULL) 검사는 전적으로 필요하지 않습니다. 또한 주 처리 블록의 예외와 다르게 close()에 대한 예외를 처리하는 경우는 거의 없습니다.

+0

나는이 해결책을 좋아한다 – wutzebaer

8

자바 7 때문에 시도 - 마지막 Closeable 자원에 관해서 차단 쓸 수있는 훨씬 더 좋은 방법이있다.

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

고마워! 클로저 블 객체를 처리하는 것이 좋습니다. –