iT邦幫忙

0

day10 try-with-resources(確保 Socket 自動關閉)

  • 分享至 

  • xImage
  •  

try-with-resources形式是 try (Resource r = ...) { ... },編譯器會自動在區塊結束時呼叫 r.close()。
任何實作了 java.lang.AutoCloseable(或 java.io.Closeable) 的物件都可以放進 try-with-resources。
Socket 實作了 Closeable,所以可以放進去。
即使區塊內拋出例外,資源也會被自動關閉。若 close() 本身又拋例外,該例外會被標記為 suppressed exception(被附加到最初拋出的例外上,不會蓋掉原始例外)。

優點:程式更安全、較少資源外洩(resource leak),程式碼也更乾淨。。

「AutoCloseable」 是一個 介面(interface),定義了物件可以被自動關閉的方法。
它只有一個抽象方法:
public interface AutoCloseable {
void close() throws Exception;
}
實作這個介面的物件,可以放在 try-with-resources 裡面。
try-with-resources 會在區塊結束時自動呼叫 close(),即使程式中間拋例外,也保證資源被釋放。
所有 Closeable(例如 FileInputStream、BufferedReader)都實作了 AutoCloseable。

package day1;

import java.io.IOException;
import java.net.*;

public class Day10Demo {

public enum PortStatus {
    OPEN,
    CLOSED,
    TIMEOUT,
    UNKNOWN_HOST,
    ERROR
}

public static PortStatus checkPort(String host, int port, int timeoutMs) {
    try (Socket socket = new Socket()) {
        socket.connect(new InetSocketAddress(host, port), timeoutMs);
        // 若 connect 成功,會執行到這裡;try 區塊結束時 socket.close() 會自動被呼叫
        return PortStatus.OPEN;
    } catch (ConnectException e) {
        return PortStatus.CLOSED;
    } catch (SocketTimeoutException e) {
        return PortStatus.TIMEOUT;
    } catch (UnknownHostException e) {
        return PortStatus.UNKNOWN_HOST;
    } catch (IOException e) {
        return PortStatus.ERROR;
    }
}

public static void main(String[] args) {
    String host = "localhost";
    int[] ports = {22, 80, 8080, 9999};
    int timeoutMs = 2000;

    for (int port : ports) {
        PortStatus status = checkPort(host, port, timeoutMs);
        System.out.println("port:" + port + " 狀態:" + status);
    }
}

}

AutoCloseable:任何實作它的物件都能用在 try-with-resources,確保自動關閉。
try-with-resources:語法簡潔、避免資源外洩,也會處理 close() 拋例外的情況。
Java 7 之後建議所有 I/O 或需要釋放資源的物件都用 try-with-resources。

這段程式碼在day9做修改,今天使用 try-with-resources 自動關閉 Socket,
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(host, port), timeoutMs);
今天學到了 try-with-resources 這樣不需要手動寫 socket.close(),讓程式更乾淨,且無論 try 區塊中是否拋出例外,Socket 都會自動關閉,更安全,不會有資源洩漏的風險。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言