
“สวัสดี อามีโก้!”
"ฉันเพิ่งตัดสินใจที่จะหารือเกี่ยวกับ วิธี สุดท้าย () กับคุณ"
"ถ้าคุณจำได้ Finalize() เป็นเมธอดพิเศษที่วัตถุเรียกก่อนที่ตัวรวบรวมขยะจะทำลายมัน"
"จุดประสงค์หลักของวิธีนี้คือการเพิ่มทรัพยากรภายนอกที่ไม่ใช่ Java ที่ใช้โดยการปิดไฟล์ สตรีม I/O และอื่นๆ"
"น่าเสียดายที่วิธีนี้ไม่เป็นไปตามที่เราคาดไว้ Java virtual machine สามารถเลื่อนการทำลายอ็อบเจกต์ได้ เช่นเดียวกับการเรียกใช้เมธอดสุดท้าย ตราบใดที่มันต้องการ ยิ่งกว่านั้น มันไม่ได้รับประกันว่าวิธีนี้จะได้ผล เรียกเลย มีสถานการณ์มากมายที่ไม่ถูกเรียก ทั้งหมดนี้อยู่ในชื่อ «การเพิ่มประสิทธิภาพ»"
"ฉันมีข้อมูลอ้างอิงสองรายการสำหรับคุณ:"
Joshua Bloch ได้เขียนบทความที่ดีเกี่ยวกับวิธีนี้: ลิงก์ ฉันจะถอดความข้อความที่ตัดตอนมาสั้นๆ:
|
ถ้าฉันพูดในการสัมภาษณ์ว่า Finalize เป็นไม้ยันรักแร้ที่ร้ายกาจและอันตราย ซึ่งการมีอยู่ของมันทำให้เกิดความสับสน ฉันจะพูดถูกไหม? |
“นั่นทำให้วันของฉันดีขึ้น เอลลี่”
"Java 7 มีคำสั่งใหม่เพื่อแทนที่เมธอด endizeซึ่งเรียกว่าtry-with-resourcesมันไม่ใช่การแทนที่finalizeแต่เป็นวิธีทางเลือก"
"มันเหมือนกับการลองจับ แต่มีทรัพยากรหรือไม่"
"เกือบจะเหมือนกับการ try-catchสิ่งต่าง ๆ คือไม่เหมือนกับเมธอดFinalize () บล็อก สุดท้ายใน คำสั่ง try- catch-finalจะถูกดำเนินการเสมอ โปรแกรมเมอร์ยังใช้เทคนิคนี้เมื่อต้องการเพิ่มทรัพยากร ปิดเธรด ฯลฯ
"นี่คือตัวอย่าง:"
InputStream is = null;
try
{
is = new FileInputStream("c:/file.txt");
is.read(…);
}
finally
{
if (is != null)
is.close();
}
"ไม่ว่า บล็อก tryจะดำเนินการอย่างถูกต้องหรือมีข้อยกเว้น บล็อก สุดท้ายจะถูกเรียกเสมอ และเป็นไปได้ที่จะปล่อยทรัพยากรที่ถูกครอบครองที่นั่น"
"ดังนั้นใน Java 7 จึงมีการตัดสินใจที่จะทำให้แนวทางนี้เป็นทางการ เช่น:"
try(InputStream is = new FileInputStream("c:/file.txt"))
{
is.read(…);
}
" คำสั่งการลองแบบ พิเศษนี้ เรียกว่าการลองใช้ทรัพยากร
"โปรดสังเกตว่าหลังจากการ try จะมีวงเล็บซึ่งมีการประกาศตัวแปรและสร้างวัตถุ วัตถุเหล่านี้สามารถใช้ภายในบล็อกการลองที่ระบุโดยวงเล็บปีกกา เมื่อการดำเนินการบล็อกการพยายามเสร็จสิ้นไม่ว่าจะสิ้นสุดตามปกติหรือตรงนั้น เป็นข้อยกเว้น วิธีการปิด () จะถูกเรียกบนวัตถุใด ๆ ที่สร้างขึ้นภายในวงเล็บ"
"น่าสนใจจัง! เครื่องหมายนี้กระชับกว่าอันที่แล้วมาก ฉันยังไม่แน่ใจว่าจะเข้าใจไหม"
"ไม่ยากอย่างที่คิด"
"ฉันสามารถระบุคลาสของแต่ละวัตถุในวงเล็บได้หรือไม่"
"ใช่ แน่นอน มิฉะนั้นวงเล็บจะมีประโยชน์เพียงเล็กน้อย"
"และถ้าฉันต้องการเรียกใช้เมธอดอื่นหลังจากออกจากบล็อกลอง ฉันจะใส่ไว้ที่ไหน"
"สิ่งต่าง ๆ ละเอียดขึ้นเล็กน้อยที่นี่ Java 7 แนะนำอินเทอร์เฟซต่อไปนี้:"
public interface AutoCloseable
{
void close() throws Exception;
}
"คลาสของคุณสามารถใช้อินเทอร์เฟซนี้ จากนั้นคุณสามารถใช้วัตถุภายในคำสั่ง try-with-resources ได้ เฉพาะวัตถุดังกล่าวเท่านั้นที่สามารถสร้างได้ภายในวงเล็บของคำสั่ง try-with-resource สำหรับ «ปิดอัตโนมัติ»"
"กล่าวอีกนัยหนึ่ง ฉันต้องแทนที่เมธอด close และเขียนโค้ดในนั้นเพื่อ «ล้างข้อมูล» วัตถุของฉัน และฉันไม่สามารถระบุเมธอดอื่นได้"
"ใช่ แต่คุณสามารถระบุวัตถุหลายชิ้นได้ เพียงแค่คั่นด้วยเครื่องหมายอัฒภาค:"
try(
InputStream is = new FileInputStream("c:/file.txt");
OutputStream os = new FileOutputStream("c:/output.txt")
)
{
is.read(…);
os.write(…);
}
"ดีขึ้น แต่ไม่เจ๋งเท่าที่ฉันหวังไว้"
“ก็ไม่แย่เท่าไหร่ เดี๋ยวก็ชินเอง เมื่อเวลาผ่านไป”