ฉันเห็นรหัสบางอย่างเช่นนี้:
try
{
db.store(mydata);
}
finally
{
db.cleanup();
}
ฉันคิดว่าtry
ควรจะมีcatch
?
ทำไมโค้ดนี้ถึงทำแบบนี้?
ฉันเห็นรหัสบางอย่างเช่นนี้:
try
{
db.store(mydata);
}
finally
{
db.cleanup();
}
ฉันคิดว่าtry
ควรจะมีcatch
?
ทำไมโค้ดนี้ถึงทำแบบนี้?
คำตอบ:
สิ่งนี้มีประโยชน์หากคุณต้องการให้วิธีการดำเนินการในปัจจุบันยังคงทิ้งข้อยกเว้นในขณะที่อนุญาตให้ล้างทรัพยากรอย่างเหมาะสม ด้านล่างนี้เป็นตัวอย่างที่เป็นรูปธรรมของการจัดการข้อยกเว้นจากวิธีการโทร
public void yourOtherMethod() {
try {
yourMethod();
} catch (YourException ex) {
// handle exception
}
}
public void yourMethod() throws YourException {
try {
db.store(mydata);
} finally {
db.cleanup();
}
}
catch
บล็อกข้อยกเว้นที่เกิดขึ้นfinally
จะถูกดำเนินการก่อนข้อยกเว้นใด ๆ ในtry
บล็อก ดังนั้นหากมีสองข้อยกเว้นหนึ่งtry
และเป็นหนึ่งในข้อยกเว้นเพียงคนเดียวที่จะถูกโยนเป็นหนึ่งในfinally
finally
ลักษณะการทำงานนี้จะไม่เหมือนกันใน PHP และ Python เป็นทั้งข้อยกเว้นจะถูกโยนในเวลาเดียวกันในภาษาเหล่านี้และคำสั่งข้อยกเว้นเป็นครั้งแรกแล้วtry
finally
ที่นั่นเป็นเพราะโปรแกรมเมอร์ต้องการให้แน่ใจว่าdb.cleanup()
มีการเรียกใช้แม้ว่าโค้ดในบล็อกลองจะมีข้อยกเว้นก็ตาม ข้อยกเว้นใด ๆ จะไม่ได้รับการจัดการโดยบล็อกนั้น แต่จะเผยแพร่ขึ้นไปหลังจากที่บล็อกในที่สุดเสร็จสิ้นแล้ว
try
finally
ไม่มีข้อยกเว้น
ทำไมโค้ดนี้ถึงทำแบบนี้?
เนื่องจากเห็นได้ชัดว่าโค้ดไม่ทราบวิธีจัดการกับข้อยกเว้นในระดับนี้ ไม่เป็นไร - ตราบใดที่ผู้โทรคนใดคนหนึ่งทำเช่นตราบใดที่ข้อยกเว้นได้รับการจัดการในที่สุด
บ่อยครั้งรหัสระดับต่ำไม่สามารถตอบสนองต่อข้อยกเว้นได้อย่างเหมาะสมเนื่องจากผู้ใช้จำเป็นต้องได้รับการแจ้งเตือนหรือต้องบันทึกข้อยกเว้นหรือต้องลองใช้กลยุทธ์อื่น โค้ดระดับต่ำจะดำเนินการอย่างใดอย่างหนึ่งฟังก์ชั่นเท่านั้นและไม่ทราบเกี่ยวกับการตัดสินใจในระดับที่สูงขึ้น
แต่โค้ดยังคงต้องการทำความสะอาดทรัพยากร (เพราะถ้าไม่เป็นเช่นนั้นก็จะรั่วไหล) ดังนั้นจึงทำเช่นนั้นในส่วนfinally
คำสั่งเพื่อให้แน่ใจว่าจะเกิดขึ้นเสมอไม่ว่าจะมีข้อยกเว้นหรือไม่ก็ตาม
บล็อกสุดท้ายช่วยให้มั่นใจได้ว่าแม้ว่า RuntimeException จะถูกโยนทิ้งไป (อาจเกิดจากข้อผิดพลาดบางอย่างในรหัสที่เรียก) การdb.cleanup()
โทรจะถูกสร้างขึ้น
นอกจากนี้ยังมักใช้เพื่อป้องกันการทำรังมากเกินไป:
try
{
if (foo) return false;
//bla ...
return true;
}
finally
{
//clean up
}
โดยเฉพาะอย่างยิ่งเมื่อมีหลายจุดที่วิธีการส่งคืนสิ่งนี้จะช่วยเพิ่มความสามารถในการอ่านเนื่องจากทุกคนสามารถเห็นรหัสการล้างข้อมูลที่เรียกว่าในทุกกรณี
รหัสกำลังทำเพื่อให้แน่ใจว่าฐานข้อมูลถูกปิด
โดยปกติวิธีที่คุณจะทำคือใส่รหัสการเข้าถึงฐานข้อมูลทั้งหมดของคุณในบล็อกลองจากนั้นจึงทำการโทรเพื่อปิดฐานข้อมูลในบล็อกสุดท้าย
วิธีลอง ... ในที่สุดก็ใช้งานได้หมายความว่าโค้ดในบล็อกลองถูกรันและโค้ดในบล็อกสุดท้ายจะทำงานเมื่อเสร็จสิ้น ... ไม่ว่าจะเกิดอะไรขึ้น
สั้น ๆ ของคอมพิวเตอร์ที่ถูกดึงออกจากผนังในที่สุดก็จะดำเนินการ
ซึ่งหมายความว่าแม้ว่าจะมีการเรียกข้อยกเว้นและวิธีการนี้ใช้เวลาสามปีในการดำเนินการ แต่ก็จะยังคงอยู่ในบล็อกสุดท้ายและฐานข้อมูลจะถูกปิด
หากรหัสใด ๆ ในบล็อก try สามารถทำให้เกิดข้อยกเว้นที่ตรวจสอบได้รหัสนั้นจะต้องปรากฏในส่วนคำสั่งพ่นของลายเซ็นวิธีการ หากข้อยกเว้นที่ไม่ได้ทำเครื่องหมายถูกโยนออกไปข้อยกเว้นนั้นจะถูกทำให้เกิดฟองออกจากวิธีการ
สุดท้ายบล็อกจะถูกดำเนินการเสมอไม่ว่าจะมีข้อยกเว้นหรือไม่ก็ตาม
fopen
หรือการเชื่อมต่อ DB (ใน PHP)