2013-07-02 5 views
5

AutoCloseable을 구현하는 클래스가 있으며 Java 7의 새로운 try-with-resources 구성에 사용하기위한 것입니다. 그러나, 나는 내 수업의 사용자가 자원을 사용하는 것을 보장하는 방법을 이해할 수 없다. 이것이 일어나지 않으면 내 수업이 닫히지 않을 것이고 나쁜 일이 일어날 것입니다. 이것을 시행하기위한 언어 구성 또는 기타 방법이 있습니까? try-with-resources 블록에 있는지 여부를 감지 할 수 있어도 컴파일 타임 구성이 바람직 할 수는 있지만 예외가 발생하지 않으면 예외를 throw 할 수 있습니다.자원을 강제로 사용하십시오 Java 7

감사합니다.

+0

try-with-resources를 사용하여 자동으로 대신 클래스를 수동으로 관리하려는 사용자는 무엇입니까? 'close'라고 불리는'finalize' 메소드를 만들면 문제가 해결 될까요? – Jeffrey

+0

불행히도'finalize'는 호출 될 수 없다는 것을 의미합니다. GC가 호출하지 않기로 결정할 수도 있습니다. – joshlf

+0

사실,'finalize '의 신뢰할 수 없다는 것이 아마도 리소스가있는 try-with-resources가 도입 된 것이라고 생각합니다. – joshlf

답변

3

불행히도 사용자 어리 석음으로부터 자신을 보호 할 방법이 없습니다.

finalize 메서드를 구현하여 close을 호출 할 수 있습니다. 이 방법을 사용하면 언제든지 객체가 가비지 수집 될 때 리소스가 닫혀 있는지 여부를 알 수 있습니다.

프로젝트 사용 방법에 제한을 둘 수있는 경우에는 aspect 지향 프로그래밍을 사용하여 일부 정책을 시행 할 수 있지만 더 이상 Java를 사용하지 않을 수 있습니다. 분별있는 자원이 사용 범위 내에서 discarted 할 수있는 경우

+1

Object.finalize()의 사용은 java에서는 사용하지 않는 것이 좋습니다. –

+0

당신이하고있는 일을 안다면 * 그리고 * 다른 선택권이 없다면) – Joni

+2

@DavidHofmann : 나는 당신이 뭔가 잘못 이해했다고 생각합니다. 아마도 GC에 의해 호출되는 finalize에 의존하기를 꺼리는 것이지만 (실제로는 이유가 있습니다.) 실제로 finalize 메소드를 구현하는 것이 경우에 따라 리소스 유출을 막는 유일한 방법입니다. – jarnbjo

-1

아니, ... 파일이나 데이터베이스 연결을 열고 유지하고 당신이 그들을 닫지 않는 경우 방법은, 같은 나쁜 일이 일어날 것

있다 한 메서드 호출의 경우 api가 호출 될 때마다 열거 나 닫을 수 있습니다. 그렇지 않은 경우 제대로 동작을 문서화 한 것입니다.

클래스도 종료 훅을 등록 할 수 있으므로 jvm이 다운 될 때 최소한 리소스를 닫을 수는 있지만 어쨌든 라이브러리에 대한 나쁜 방법이라고 생각합니다.

+1

틀렸어. 자원 누출을 막을 수있는 마지막 가능성으로 각 랩퍼 인스턴스를 마무리 할 때 파일과 네트워크 또는 데이터베이스 연결이 모두 닫힙니다. 자체 구현을 위해 동일한 구현 패턴을 사용하지 않을 이유가 없습니다. – jarnbjo

+0

설명을 위해 @jarnbjo에게 감사드립니다. 내가 생각한 것은 비록 당신이 그들을 닫지 않고 자원을 열어두면 누출이 있다는 것입니다. 어쨌든 나중에 누수를 보는 것이 더 낫다고 생각합니다. 언젠가는 닫히지 않은 객체에 대한 참조를 유지하는 경우에는 finalize 메서드가 호출되지 않습니다. GC를 사용하는 경우 프로그램을 실행하는 램과 gc 튜닝의 양에 따라 결정적이지 않은 동작을 할 수 있습니다 –

1

리소스 관리에 정말로 관심이 있다면 콜백 관용구를 사용하는 것이 가장 안전한 방법입니다.

: 당신이 조기 종료를 지원하려면

public interface Callback<T> { 
    void handle(T item); 
} 

public class SuperVitalVault { 
    public void all(Callback<Precious> callback) { 
    try (...) { 
     for (Precious i : ...) { 
     callback.handle(i); 
     } 
    } 
    } 
} 

당신은 boolean을 반환 Callback.handle(T)을 변경할 수 있습니다 : 당신은 최종 사용자가 컬렉션의 항목을 처리 할 수 ​​있습니다 수집,하지만 API를 노출하지 마십시오 당신이 당신의 자신의 콜백 인터페이스를 정의 멀리하려면

try (...) { 
     for (Precious i : ...) { 
     if (callback.handle(i)) break; 
     } 
    } 

, 당신은 사용 구아바의 Function<T, Boolean> 또는 Predicate<T>하지만 구아바에 의해 설립 된 의미 위반 참고 할 수 있습니다

0123을

함수 인스턴스는 일반적으로 참조 효과가 있으며 부작용이없고 equals와 일관성이 있다고 기대됩니다. 즉, a.equals (b)는 function.apply (a) .equals (function.apply 비)).

술어의 인스턴스는 일반적으로 부작용이없고 equals와 일치해야합니다.