差異處
這裏顯示兩個版本的差異處。
Both sides previous revision 前次修改 下次修改 | 前次修改 | ||
java:basic:close_systemin_of_scanner [2016/11/30 10:37] tony |
java:basic:close_systemin_of_scanner [2023/06/25 09:48] (目前版本) |
||
---|---|---|---|
行 4: | 行 4: | ||
如果有寫到CLI的tool,使用Scanner物件是很平常的事情,因此應會遇到是否該close Scanner物件的問題。假如有兩個類別都會使用到使用System.in的Scanner,先close的就會讓後面的發生問題。 | 如果有寫到CLI的tool,使用Scanner物件是很平常的事情,因此應會遇到是否該close Scanner物件的問題。假如有兩個類別都會使用到使用System.in的Scanner,先close的就會讓後面的發生問題。 | ||
===== Solutions ===== | ===== Solutions ===== | ||
- | 閱讀幾篇文章後,作法有以下: | + | 閱讀幾篇文章後,有以下做法: |
- 不理它,反正不會造成memory leak。 | - 不理它,反正不會造成memory leak。 | ||
- | - 使用Decorator方式,將System.in包裝在不會真的close的InputStream中。 | + | - 使用Decorator樣式,將System.in包裝在不會真的close的InputStream中。 |
- | - 使用Global Scanner。 | + | - 使用Singleton樣式,大家都用同一個Global Scanner。 |
+ | 第一個做法對於寫code有潔癖的人來說,不會去使用的。而第二和第三個做法,以單元測試方便性來說與,我比較偏愛Decorator方式;使用Singleton的作法,還要考慮到底是誰負責close。如果大家都說好,你可以透過shutdown hook去close。 | ||
+ | \\ | ||
+ | \\ | ||
+ | 分享decorator作法,參考apache common io程式碼: | ||
+ | <code java> | ||
+ | public class CloseShieldInputStream extends ProxyInputStream { | ||
+ | |||
+ | /** | ||
+ | * Creates a proxy that shields the given input stream from being | ||
+ | * closed. | ||
+ | * | ||
+ | * @param in underlying input stream | ||
+ | */ | ||
+ | public CloseShieldInputStream(InputStream in) { | ||
+ | super(in); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Replaces the underlying input stream with a {@link ClosedInputStream} | ||
+ | * sentinel. The original input stream will remain open, but this proxy | ||
+ | * will appear closed. | ||
+ | */ | ||
+ | public void close() { | ||
+ | in = new ClosedInputStream(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | Client可以這樣使用: | ||
+ | <code java> | ||
+ | try( Scanner scanner = new Scanner(new CloseShieldInputStream(System.in))){ | ||
+ | // some operations | ||
+ | } | ||
+ | </code> | ||
===== Reference ===== | ===== Reference ===== | ||
* [[http://stackoverflow.com/questions/14142853/close-a-scanner-linked-to-system-in|close-a-scanner-linked-to-system-in]] | * [[http://stackoverflow.com/questions/14142853/close-a-scanner-linked-to-system-in|close-a-scanner-linked-to-system-in]] | ||
行 13: | 行 48: | ||
* [[http://stackoverflow.com/questions/23621668/java-closing-scanner-and-resource-leak|java-closing-scanner-and-resource-leak]] | * [[http://stackoverflow.com/questions/23621668/java-closing-scanner-and-resource-leak|java-closing-scanner-and-resource-leak]] | ||
+ | ===== ===== | ||
+ | ---- | ||
+ | \\ | ||
+ | ~~DISQUS~~ |