2013-04-30 37 views
2

所以Java 7有一個漂亮的功能,可自動關閉的AutoCloseable類。如果我有Bar實現Closeable(這又延伸AutoCloseable),並有辦法從Foo得到一個開放Bar,我可以這樣做:手動打開一個Java 7的自動管理資源

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

...和bar將會被自動關閉,只就好像它被放在finally條款中一樣。可愛。

但是如果我想獲得一個Bar後來打開它?因爲也許Bar就像是File和僅僅識別的資源;我可能想識別它們中的很多,但只有在必要時纔打開它們。

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

但是Java 7的自動管理方法需要我去try子句中指定一個變量,不是嗎?

所以也許我可以巧妙和有Bar.open()回報this(即Bar實例),這樣我可以做到這一點:

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()引發異常呢? Java 7中會嘗試關閉bar,這在我的實現,將拋出IllegalStateException,因爲你不能說從來沒有打開過密切的東西。所以它應該,對吧?因爲如果有人試圖已經打開它之前關閉Bar實例,東西是扭曲的,我們希望有一個快速失敗的方法,而不是在一個未知的時間讓問題宣傳和表面。

但也許我真的使用自動資源管理,所以我考慮放寬Bar.close(),讓您可以隨時關閉它,即使你沒有打開的Bar。但現在看看我在做什麼:我正在改變我的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

第一個幾乎否定語法糖 - 也許我們可以稱之爲_syntactic苦澀! :)但第二個選項很有趣;我會更多地考慮它... – 2013-04-30 20:41:22

0

啊,我有!我將在API中使用兩種截然不同的方法!一個將是Foo.getBar(),它只返回一個Bar實例。第二個將是Foo.openBar(),這僅僅是第一次調用Foo.getBar()的便捷方法,然後調用Bar.open()這樣的:

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

通過這種方式,可以通過調用Foo.openBar()使用自動資源管理:

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

當人們想簡單地得到一個Bar實例稍後使用時,可以調用Foo.getBar()。不幸的是,如果您稍後再打開它,這仍然不允許您執行自動資源管理,但也許這種方法將滿足常見用例,同時仍允許靈活性。

相關問題