2014-10-22 2 views
16

코드를 살펴본 결과 리소스를 사용해 보았습니다. 이전에 표준 try-catch 문을 사용했으며 동일한 작업을 수행하는 것처럼 보입니다. 그래서 내 질문은 입니다 리소스와 함께 시도하십시오 - 캐치 그들 사이의 차이점은 무엇이며 더 낫다. 여기 리소스와 시도 Try-Catch

자원과 시도이다

objects jar = new objects("brand"); 
objects can= new objects("brand"); 

try (FileOutputStream outStream = new FileOutputStream("people.bin")){ 
    ObjectOutputStream stream = new ObjectOutputStream(outStream); 

    stream.writeObject(jar); 
    stream.writeObject(can); 

    stream.close(); 
    } catch(FileNotFoundException e) { 
     System.out.println("sorry it didn't work out"); 
    } catch(IOException f) { 
     System.out.println("sorry it didn't work out"); 
    } 
+3

차이점은 try-wth-resource에서 stream.close()를 호출 할 필요가 없다는 것입니다. 마지막으로 finally 절을 닫으면 자동으로 호출됩니다. Closeable 또는 AutoCloseable을 암시하는 객체 만 try-with-resouce 절에서 사용할 수 있습니다. – sturcotte06

+2

'try {..}'섹션에'stream.close();'를 호출 할 필요는 없습니다. try-with-resources가 처리 할 "finally"섹션에서 수행되어야합니다 (BTW try-with-resources는 여러 자원을 처리 할 수 ​​있습니다). – Pshemo

답변

26

주요 지점처럼 확인되어 있는지 확인합니다 응용 프로그램 코드가 필요없이 자원이 닫힙니다. 그러나 고려해야 할 몇 가지 미세한 점이 있습니다.

리소스를 사용하지 않으면 예외 마스킹이라는 잠재적 인 함정이 있습니다. try 블록의 코드가 예외를 throw하고 finally 메서드의 close 메서드도 예외를 throw하면 try 블록에 의해 throw 된 예외가 손실되고 finally에서 throw 된 예외가 전파됩니다. 유용한 예외가 유익한 예외 인 반면, 닫히는 예외는 도움이되지 않기 때문에 이것은 일반적으로 불행합니다. try-with-resources를 사용하여 리소스를 닫으면 예외 마스킹이 발생하지 않습니다.

예외 마스크가 중요한 예외 정보를 잃지 않도록하기 위해 try-with-resources가 개발되었을 때 그들은 close 메소드에서 던져진 예외 사항을 어떻게 처리해야하는지 결정해야했습니다. 와

시도 -과 - 자원, try 블록에서 예외가 발생하고 close 메소드는 다음 the exception from the close block gets tacked on to the original exception 예외를 슬로우하는 경우 :

... 두 개의 독립적 인 예외에 던져 질 수있는 상황이있다 형제 코드 블록, 특히 try-with-resources 문과 리소스를 닫는 컴파일러에서 생성 된 finally 블록의 try 블록에 있습니다. 이러한 상황에서는 throw 된 예외 중 하나만 전파 할 수 있습니다. try-with-resources 문에는 이러한 두 개의 예외가있는 경우 try 블록에서 발생한 예외가 전파되고 finally 블록의 예외가 try 블록의 예외로 표시되지 않는 예외 목록에 추가됩니다. 예외가 스택을 풀면 여러 억제 된 예외가 누적 될 수 있습니다.

반면에 코드가 정상적으로 완료되었지만 사용중인 리소스가 close시 예외를 throw하면 해당 예외 (try 블록의 코드가 아무 것도 버리면 표시되지 않음)가 발생합니다. 따라서 try-with-resources를 사용하여 ResultSet 또는 PreparedStatement를 닫는 JDBC 코드가있는 경우 JDBC 객체가 닫힐 때 일부 인프라 결함으로 인한 예외가 발생하여 성공적으로 완료된 작업을 롤백 할 수 있습니다.

리소스가없는 try-with-with 리소스없이 close 메서드 예외가 throw되는지 여부는 응용 프로그램 코드에 달려 있습니다.try 블록이 예외를 throw 할 때 finally 블록에 던져지면 finally 블록의 예외는 다른 예외를 마스크합니다. 그러나 개발자는 닫을 때 던져진 예외를 잡아서 전파하지 않을 수 있습니다.

+0

"try"에서 던져진 예외 (있는 경우)를 찾아 내기 위해 "finally"블록에 쉬운 방법이 있었으면 좋겠다. 그래서 같은 종류의 전파 - 정리 - 예외 - if-no- 사용자 코드에서 다른 논리가 보류 중입니다. – supercat

2

유일한 차이점은, 당신은 뭔가를 놓친 finally 블록

4

finally 블록을하는 것처럼 그 시도-자원이 자동으로 resource.close(); 을 추가합니다. try-with-resouces은 무언가 당신이 정말로 (결코 제비 예외) 같은 것을 원하는 의미

FileOutputStream outStream = null; 
try { 
    outStream = new FileOutputStream("people.bin"); 
    ObjectOutputStream stream = new ObjectOutputStream(outStream); 

    stream.writeObject(jar); 
    stream.writeObject(can); 

    stream.close(); 
} catch(FileNotFoundException e) { 
    System.out.println("sorry it didn't work out"); 
} catch(IOException f) { 
    System.out.println("sorry it didn't work out"); 
} finally { 
    if (outStream != null) { 
    try { 
     outStream.close(); 
    } catch (Exception e) { 
    } 
    } 
} 

, 시도 -과 - 자원의

try (FileOutputStream outStream = new FileOutputStream("people.bin"); 
    ObjectOutputStream stream = new ObjectOutputStream(outStream);) { 
    stream.writeObject(jar); 
    stream.writeObject(can); 
    // stream.close(); // <-- closed by try-with-resources. 
} catch(FileNotFoundException e) { 
    System.out.println("sorry it didn't work out"); 
    e.printStackTrace(); 
} catch(IOException f) { 
    System.out.println("sorry it didn't work out"); 
    e.printStackTrace(); 
} 
+0

stream.close(); 어쨌든 마지막 블록에서 스트림이 닫히기 때문에 try 블록에서 불필요합니다. – UDPLover

+0

@Meraman 나는 나의 대답의 마지막 부분에서 그것을 언급했다. OP 질문에는 * finally * 블록이 없습니다. –

0

java.lang.AutoCloseable 또는 java.io.Closeable 을 구현하는 모든 객체 (클래스 또는 해당 수퍼 클래스)는 try-with-resource 절에서만 사용할 수 있습니다. AutoClosable 인터페이스는 부모 인터페이스이며 Closable 인터페이스는 AutoClosable 인터페이스를 확장합니다 .AutoClosable 인터페이스에는 close 메소드가 있으며 Exception을 throw하고 Closable 인터페이스에는 IOException을 throw합니다. try-with-resource 절 안에 선언 된 리소스가 닫힌 후에 catch 및 finally 블록과 try-with-resource가 차례대로 일반 try, catch 및 finally처럼 실행되지만 catch 및 finally 블록 만 실행됩니다.

관련 문제