2013-04-30 1 views
2

Java 7에는 AutoCloseable 클래스를 자동으로 닫는 멋진 기능이 있습니다. 다만,수동으로 Java 7 자동 관리 리소스 열기

try(Bar bar=foo.openBar()) 
    //do something 
} 

을 ... 그리고 bar가 자동으로 종료됩니다 : 내가 가지고있는 BarCloseable을 (다시 AutoCloseable를 확장하는)를 구현하고, Foo에서 열린 Bar을 얻을 수있는 방법이있는 경우,이 작업을 수행 할 수 있습니다 마치 finally 절에있는 것처럼. 아름다운.

하지만 Bar을 받고 나중에 열려면 어떻게해야합니까? 아마도 BarFile과 같아서 단순히 자원을 식별하기 만합니다. 나는 그것들을 많이 식별하려고 할 수 있지만 필요할 때만 열어 놓을 수 있습니다.

Bar bar=foo.getBar(); 
try(bar.open()) //doesn't work 
    //do something 
} 

그러나 자바 7 자동 관리 접근 방식은 아니, try 절에 변수를 할당하는 저를 필요로?

그래서 어쩌면 내가 영리하고 (즉, Bar 예) Bar.open() 반환 this을 가지고, 나는이 할 수 있도록 할 수 있습니다 내가 원하는대로

try(Bar bar=foo.getBar().open()) 
    //do something 
} 

이 기능을하지만, 나에게 그 경고를 표시합니다 중간 Bar 인스턴스가 닫히지 않습니다.

그래서 어쩌면 내가이 작업을 수행 할 수 있습니다

Bar bar=foo.getBar(); 
try(Bar temp=bar.open()) 
    //do something 
} 

를이 너무 내가 원하는 방식으로 기능하지만, 지옥 같은 추악한되고 게다가, 난 여전히 경고를 얻을 --- 이번에는 처음 bar 변수는 결코 없다 닫은.

그래서 어쩌면이 같은 보호 된 블록 내부의 bar.open() 전화를 넣을 수 있습니다 : 내가 원하는 방식으로 작동합니다

try(Bar bar=foo.getBar()) 
    bar.open(); 
    //do something 
} 

--- 대부분의 시간을. 하지만 bar.open()이 예외를 throw하면 어떻게 될까요? Java 7은 bar을 닫으려고 시도합니다. 제 구현에서 결코 열리지 않은 것을 닫을 수 없기 때문에 IllegalStateException을 던집니다. 그리고 그렇게해야합니다, 그렇죠? 왜냐하면 어떤 사람이 열려고하기 전에 Bar 인스턴스를 닫으려고하면 뭔가 문제가 발생하기 때문에 알려지지 않은 시간에 문제가 전파되고 표면에 빠지게하는 대신 실패 빠른 접근 방식을 원하기 때문입니다.

하지만 어쩌면 난 정말 자동 자원 관리를 사용하려면 , 당신은 언제든지 닫을 수 있도록 그래서 당신이 Bar를 개설하지 않은 경우에도, Bar.close() 편안한 고려. 하지만 지금 내가하고있는 것을 보아라. 필자는 구문 론적 컴파일러 설탕을 사용하기 위해 API를 변경하고있다 (논란의 여지는 있지만, 열등하게 만든다) !!

다른 아이디어? Java 7이 자동으로 리소스를 닫을 수 있도록 Java 7 자동 리소스 관리를 사용하고 싶습니다. 그러나 은 언제 열어야 할지를 결정하고 싶습니다. 현재 을 획득하고 리소스를 획득해야합니다.

답변

1

하나의 아이디어시키는에 대해이 두 번 폐쇄하고이 작업을 수행 할 어떤

:

여전히 매우 추한하고 설탕 작업을 할 코드를 작성해야합니까
try (Bar bar=foo.getBar()) { 
    try(bar=bar.open()) { 
    //do something 
    } 
} 

.

또 다른 아이디어

또는 단지 두 개의 클래스가 있습니다. 하나는 당신이 그것을 열 때까지 상태 정보를 보유하고 있습니다. 그런 다음 처음부터 만들어내는 또 다른 것이 있으며 실제로 열립니다. (정렬의 FileFileInputStream. 등)

BarInfo barInfo = foo.getBarInfo(); 
... 
try (Bar bar = barInfo.open()) { 
    // do stuff with it 
} 
+1

첫 번째 문법적인 설탕을 거의 무효로합니다. 아마도 우리는 그것을 syntatic bitter_라고 부를 수 있습니다! :)하지만 두 번째 옵션은 흥미 롭습니다. 나는 그것에 대해 더 생각할 것이다 ... –

0

아, 나는 그것을있다! API에는 두 가지 별개의 메소드가 있습니다. 하나는 Foo.getBar()이고 이는 단순히 Bar 인스턴스를 반환합니다. 두 번째는 첫 번째 Foo.getBar()를 호출 만하는 편리한 방법입니다 Foo.openBar() 될 다음과 같은 Bar.open() 호출됩니다

public Bar openBar() { 
    Bar bar=getBar(); 
    bar.open(); 
    return bar; 
} 

이 방법은, 하나 Foo.openBar()를 호출하여 자동 자원 관리를 사용할 수 있습니다

try(Bar bar=foo.openBar()) { 
    //do something 
} 

Bar 인스턴스를 나중에 사용하려면 Foo.getBar()으로 전화하면됩니다. 유감스럽게도 나중에 이것을 열 때까지 기다리지 않으면 자동 리소스 관리를 수행 할 수 없지만 융통성을 허용하면서 일반적인 사용 사례를 만족시킬 수 있습니다.