差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

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~~