[Java] try-with-resouces กับการคืนทรัพยากรบน Java 7

          Java 7 มี syntax ที่เราอาจไม่ได้รู้สึกตัวว่ามันมีอยู่ คราวนี้เราก็จะมาทำความรู้จัก try-with-resources ที่เป็นตัวช่วยสำคัญในการยุ่งกับ resources ต่าง ๆ เช่น การเชื่อมต่อฐานข้อมูล(Database connection) การเขียน-อ่านไฟล์ เป็นต้น

          ปกติแล้ว การเขียนโปรแกรมขั้นพื้นฐาน ก็เราได้รู้จักการใช้งาน object ซึ่งก็จะมี lifetime ของตัวมันเองแต่ก่อน การยุ่งกับ resources เราจำเป็นจะต้องเขียนเปิด-ปิดการใช้งานเอง จุดนี้ try-with-resources จะเข้ามาช่วยให้เราเขียนโค้ดง่ายขึ้น

การเชื่อมต่อฐานข้อมูลโดยไม่ใช้ try-with-resourcs 

ถ้าเขียนตามจินตนาการขั้นแรกสุด
  • เปิดใช้งาน resources
  • อย่าลืมปิดเมื่อใช้เสร็จ
Connection con = getConnection();
...
..
.
con.close()
          แต่ แต่ แต่ ! การเรียกใช้งาน resources ส่วนใหญ่จะพ่วงกันมาหลายตัว และจะบังคับให้เราเขียน try-catch เพื่อจัดการบางอย่างเมื่อเกิดปัญหาขึ้น ซึ่งเราจะต้องตามปิด resources ทั้งเคสที่ทำงานถูกต้องและไม่ถูกต้องของทุกตัว
Connection con = null;
Statement stm = null;
ResultSet rs = null;
try {
    String sql = "SELECT * FROM UserAccount";
    con = getConnection();
    stm = con.createStatement();
    rs = stm.executeQuery(sql);

    while(rs.next()) {
        rs.getString("USERNAME");
        rs.getString("EMAIL");
    }

} catch (SQLException sqle) {

} finally {
    closeResource(rs, stm, con);
} 
          วิธีที่ดีที่สุดของแบบเก่าคือ การทำเป็น method และเรียกใน finally ของ try-catch block เนื่องจากจะทำงานทุกกรณี แต่ถึงอย่างนั้นก็เถอะ มันก็ให้ความรู้สึกแหม่ง ๆ ลองดูใน method ตัวอย่างครับ
public static void closeResource(ResultSet rs, Statement stm, Connection con) {
    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException e) {}
    }
    if (stm != null) {
        try {
            stm.close();
        } catch (SQLException e) {}
    }
    if (con != null) {
        try {
            con.close();
        } catch (SQLException e) {}
    }
}

การเชื่อมต่อฐานข้อมูลโดยใช้ try-with-resources

          try-with-resources จะมาช่วยเราจัดการกับทรัพยากรที่จำเป็นต้องปิด โดยใช้ syntax ของ try และเพิ่มความสามารถเข้าไป
try (/* resources declaration */ ) {

/* statement block */

}
          เราสามารถใช้งานโดยไม่ต้องคิดเรื่องจะปิดจะเปิดอีกต่อไปแล้ว หลังจากสิ้นสุดการทำงานภายใต้ try-with-resources ก็จะถือว่าเป็นการสิ้นสุดการใช้งาน resources เช่นกัน และจะเป็นการปิดการเชื่อมต่อโดยอัตโนมัติ ไม่จำเป็นต้องเขียน close เองอีกต่อไป ลองดูตัวอย่างเต็ม ๆ กันดูครับ
String sql = "SELECT * FROM UserAccount";
try (Connection con = getConnection();
     Statement stm = con.createStatement();
     ResultSet rs = stm.executeQuery(sql);) {

    while(rs.next()) {
        rs.getString("USERNAME");
        rs.getString("EMAIL");
    }

} catch (SQLException sqle) {

} 
          จากโค้ดก่อนหน้านี้ เมื่อนำมาเปรียบเทียบกันก็ดูสั้นกว่ามาก แต่ไม่ใช่ทุก Class ที่จะเขียนให้เป็น try-with-resources ได้ ซึ่งก็มีข้อควรจำนิด ๆ หน่อย ๆ
  • JDK 7+
  • เป็น Class ที่ inherit มาจาก AutoCloseable
  • ในวงเล็บต้องเป็นการประกาศ resources เท่านั้น ไม่สามารถเติม statement อื่นได้
  • สามารถเขียน try เปล่า ๆ ได้หรือเพิ่ม catch ได้เมื่อจำเป็น (ถ้า try-catch จะไม่สามารถเขียน try ลอย ๆ ได้)

          AutoCloseable เป็น super Class / super Interface ของหลาย ๆ ตัวที่ผมยังไม่ได้พูดถึง ซึ่งทุกตัวสามารถใช้งานกับ try-with-resources ได้ นอกเหนือจากเรื่องของ database connection ก็ยังมีหลายตัวรอให้เข้าไปทดลองใช้งานกันครับ 😆

Facebook Comment

Popular post of 7 days

[Java] ความแตกต่างระหว่าง Overloading กับ Overriding

ลืมรหัสปลดล็อค Android เข้าเครื่องไม่ได้ มีทางออกครับ

[Android] เปิดเครื่องไม่ได้ โลโก้ค้าง (Boot Loop)