2013-07-12 1 views
0

는 다음과 같이 거의 끝났다 :자바 스트림을 닫는 방법? 나는 자바 6 스트림을 처리 볼 때마다

public void myMethod() throws Exception 
{ 
    InputStream stream = null; 

    try 
    { 
     stream = connection.openConnection(); 
     ... 
    } 
    finally 
    { 
     if(stream != null) 
     { 
      stream.close(); 
     } 
    } 
} 

그러나 나는이 필요한 이유를 실패합니다. 이 방식이 똑같지 않을까요? 그것은되지 openConnection()하면

public void myMethod() throws Exception 
{ 
    InputStream stream = connection.openConnection(); 

    try 
    { 
     ... 
    } 
    finally 
    { 
     stream.close(); 
    } 
} 

stream가 할당되지 않습니다 실패하고 아무것도 어쨌든 닫 없다?

+0

connection.openConnection()이 실패하면 예외가 발생합니다. try와 finally는 의미가 없으며 실패하지 않고 null 인'stream'이라고 가정하고 마침내 NullPointerException을 throw합니다. – nachokk

+0

예, 그렇지만 IOException를 방아쇠하는 스트림과의 상호 작용이있는 경우, 점에 의해 감추어지는 – Taig

+0

@nachokk하지만 메소드는 이미'Exception'을 throw합니다. 또한 아마도'stream'을 가진 어떤 연산도'Exception'을 던질 수 있습니다. –

답변

4

나는 동의합니다.

null 할당을 사용한 추가 단계는 불필요하고 추합니다. stream 결승도 할 수 있습니다.

내가 이런 식으로 쓸 수있는 유일한 시간은 정리해야 할 리소스가 두 개 이상 (JDBC가 많이 발생 함)이며 여러 중첩 try/finally 블록 (일반적으로 어쨌든 그들을 위해 가라.)

Java 7에서는 try-with 구문을 사용할 수 있습니다.

+0

에서 아래에 댓글을 달았습니다. 그런 식으로 당신은 예외를 잃을 수 있습니다 .. 뭔가 잘못된 비즈니스 예외가 발생하면 다음 스트림이 null입니다. ... 다음 stream.close() NullPointerException을 throw하고 비즈니스 예외를 잃게됩니다 .. 최종 스트림을 만드는이 예제를 해결할 수 있지만 .. – nachokk

+0

IOException 후 메서드가 종료되기 때문에'Stream.close()'호출되지 않습니다. 첫 줄에 던져진다. – Taig

+0

비즈니스 예외가 거기에 던져지고'stream'이 null이면 예외를 잃게 될 경우'try 블록 '에서 일어나는 일을 지정하지 마십시오. – nachokk

0

매번 당신은 구성체 InputStream를 검색하는 등

InputStream stream = connection.openConnection(); 

세 가지 가능한 결과가있다 : 상기 방법 중 하나는 적절한 InputStream 반환, 또는 null를 반환하거나 예외를 던진다. 세 가지 가능성에

살펴 보자는 :

1) 방법은 적절한 입력 스트림을 돌려 보냈다.

그런 경우 try 블록이 계속 진행되고 다른 문제 (일명 예외)가 발생하지 않으면 finally 블록을 실행 한 후에 정상적으로 종료됩니다.

2)이 메서드는 null을 반환합니다.

그런 경우 try 블록 내부에 null 체크가 있어야합니다. 그렇다면 try 블록은 정상적으로 아무것도 수행하지 않으며 finally 블록도 null 체크를 가져야합니다. 그렇지 않으면 finally 블록이 NPE를 던집니다.

null 반환을 막지 않으면 try 블록 내의 코드가 NPE를 throw합니다 (스트림 변수가 거기에 사용된다고 가정합니다). 이 경우, Null 검사가 없다면 finally 블록이 실행되고 NPE를 다시 던지게됩니다. 후자의 경우 finally 블록의 두 번째 NPE 만 실제로 호출자에게 전달됩니다.

3) 입력 스트림을 검색하기위한 메소드 호출에서 예외가 발생합니다.

이 경우 try 블록이 종료되어 즉시 finally 블록이 실행되고 메서드가 갑자기 종료됩니다. 그러나 예외는 무엇입니까? 조건에 따라서.

대부분의 경우 Throw되는 IOException이 던져진 예외를 고려하십시오. 우선, 변수는 여전히 null 참조를 가질 것입니다! 마지막으로 NPE가 null 체크를하지 않았다면 다시 NPE를 던집니다. 이 경우 첫 번째 예외 (IOE)는 잊어 버리게됩니다. NPE만이 메소드 호출에 전달되기 때문입니다. 그건 좋은 생각이 아니다.

모두 null 확인이 실제로 필요합니다.

이제 Java 7의 try-with-resources 구조가 제공됩니다. 스트림이 닫힌 암시 적 finally 블록이 있기 때문에 이것은 실제로 훨씬 더 좋은 메커니즘입니다. try 블록에 예외가 있고 암시 적 finally 블록에서도 예외가 발생하면 try 블록 내부의 첫 번째 예외가 호출자에게 전달됩니다. 그게 훨씬 적합합니다. 구문은 읽기가 훨씬 좋습니다.

+0

2)'URL.openConnection()'이 null을 반환 할 수 있다는 힌트가 Java 문서에 없습니다. 그것이 내 실패를 저지한다면 실패 할 것입니다. 3)'URL.openConnection()'은'try' 블록 내에서 호출되지 않는다는 것에주의하십시오. 그러므로 마침내 처형되지 않을 것입니다. 메서드 실행은 첫 번째 줄에서 멈추고'IOException'을 전달합니다. – Taig

+0

네, 맞습니다. 두 코드 스 니펫은 기술적으로 동일합니다. 실제로 저는 정적 인 유틸리티 메소드를 사용하여 스트림을 "조용히"닫습니다. 이미 한 줄의 코드 만 사용했습니다. 이것은 더 보편적이지만 Java 7에 대한 try-with-resources 문으로도 쓸모 없게되었습니다. – Seelenvirtuose

관련 문제