เฉพาะกรณีของ Java สำหรับกรณีนี้ (ซึ่งอาจคล้ายกับกรณี C #) จะทำอย่างไรกับวิธีการที่คอมไพเลอร์ Java กำหนดว่าวิธีการที่จะกลับมา
โดยเฉพาะกฎระเบียบที่มีว่าวิธีการที่มีชนิดกลับต้องไม่สามารถที่จะเสร็จสมบูรณ์ตามปกติและจะต้องแทนเสมอเสร็จสมบูรณ์ทันที (ทันทีที่นี่แสดงให้เห็นผ่านทางคำสั่งกลับหรือข้อยกเว้น) ต่อJLS 8.4.7
หากมีการประกาศให้เมธอดมีชนิดส่งคืนข้อผิดพลาดเวลาคอมไพล์จะเกิดขึ้นหากเนื้อความของเมธอดสามารถดำเนินการตามปกติ กล่าวอีกนัยหนึ่งวิธีการที่มีประเภทผลตอบแทนจะต้องกลับมาโดยใช้คำสั่งส่งคืนที่ให้ผลตอบแทนมูลค่า; มันจะไม่ได้รับอนุญาตให้ "วางปิดท้ายของลำตัว"
คอมไพเลอร์ดูเหมือนว่าการเลิกจ้างตามปกตินั้นเป็นไปได้หรือไม่ขึ้นอยู่กับกฎที่กำหนดในJLS 14.21 ประโยคที่ไม่สามารถเข้าถึงได้เนื่องจากมันจะกำหนดกฎสำหรับการทำให้สมบูรณ์ตามปกติ
โดยเฉพาะกฎสำหรับคำสั่งที่ไม่สามารถเข้าถึงได้สร้างเคสพิเศษสำหรับลูปที่มีtrue
นิพจน์คงที่ที่กำหนดไว้:
คำสั่ง while สามารถทำให้สมบูรณ์โดยปกติ iff อย่างน้อยหนึ่งอย่างต่อไปนี้เป็นจริง:
ดังนั้นหากwhile
คำสั่งสามารถดำเนินการตามปกติแล้วคำสั่งส่งคืนด้านล่างมันเป็นสิ่งจำเป็นเนื่องจากรหัสจะถือว่าสามารถเข้าถึงได้และwhile
วงใด ๆ ที่ไม่มีคำสั่งทำลายที่สามารถเข้าถึงได้หรือtrue
การแสดงออกคงที่ถือว่าสามารถทำได้ตามปกติ
กฎเหล่านี้หมายความว่าคุณwhile
คำสั่งด้วยการแสดงออกที่แท้จริงอย่างต่อเนื่องและโดยไม่ต้องbreak
มีการไม่เคยคิดว่าจะเสร็จสมบูรณ์ตามปกติและเพื่อให้รหัสใด ๆ ดังต่อไปนี้มันจะไม่เคยคิดว่าจะสามารถเข้าถึงได้ ในตอนท้ายของวิธีการที่อยู่ด้านล่างห่วงและเนื่องจากทุกอย่างด้านล่างห่วงไม่สามารถเข้าถึงเพื่อให้เป็นจุดสิ้นสุดของวิธีการและทำให้วิธีการที่ไม่อาจเสร็จสมบูรณ์ตามปกติ (ซึ่งเป็นสิ่งที่มีลักษณะเรียบเรียงสำหรับ)
if
ในทางกลับกันไม่มีข้อยกเว้นพิเศษเกี่ยวกับนิพจน์คงที่ที่สามารถวนซ้ำได้
เปรียบเทียบ:
// I have a compiler error!
public boolean testReturn()
{
final boolean condition = true;
if (condition) return true;
}
ด้วย:
// I compile just fine!
public boolean testReturn()
{
final boolean condition = true;
while (condition)
{
return true;
}
}
เหตุผลของความแตกต่างนั้นค่อนข้างน่าสนใจและเกิดจากความต้องการอนุญาตให้ใช้แฟล็กการรวบรวมแบบมีเงื่อนไขซึ่งไม่ทำให้เกิดข้อผิดพลาดของคอมไพเลอร์ (จาก JLS):
อาจคาดหวังว่าคำสั่ง if จะได้รับการจัดการในลักษณะดังต่อไปนี้:
คำสั่ง if-then สามารถดำเนินการตามปกติ iff อย่างน้อยหนึ่งอย่างต่อไปนี้เป็นจริง:
คำสั่ง if-then สามารถเข้าถึงได้ถ้า if คำสั่ง if-then สามารถเข้าถึงได้และนิพจน์เงื่อนไขไม่ใช่นิพจน์คงที่ซึ่งค่าเป็นเท็จ
คำสั่ง if-then-else สามารถดำเนินการตามปกติ iff คำสั่ง if-then สามารถดำเนินการตามปกติหรือคำสั่ง else สามารถดำเนินการตามปกติ
if-then-else สามารถเข้าถึงได้และการแสดงออกของเงื่อนไขไม่ใช่นิพจน์คงที่ซึ่งค่าเป็นเท็จ
คำสั่ง else-statement สามารถเข้าถึงได้ถ้า if คำสั่ง if-then-else สามารถเข้าถึงได้และนิพจน์เงื่อนไขไม่ใช่นิพจน์คงที่ซึ่งค่าเป็นจริง
วิธีการนี้จะสอดคล้องกับการรักษาโครงสร้างการควบคุมอื่น ๆ อย่างไรก็ตามเพื่อให้สามารถใช้คำสั่ง if เพื่อความสะดวกในการ "รวบรวมเงื่อนไข" เพื่อวัตถุประสงค์ที่แท้จริงจะแตกต่างกันไป
ตัวอย่างเช่นคำสั่งต่อไปนี้ส่งผลให้เกิดข้อผิดพลาดในการคอมไพล์เวลา:
while (false) { x=3; }
เพราะคำสั่งx=3;
ไม่สามารถเข้าถึงได้; แต่กรณีที่คล้ายกันตื้น ๆ :
if (false) { x=3; }
ไม่ส่งผลให้เกิดข้อผิดพลาดในเวลารวบรวม คอมไพเลอร์การปรับให้เหมาะสมอาจตระหนักว่าคำสั่งx=3;
จะไม่ถูกดำเนินการและอาจเลือกที่จะละเว้นรหัสสำหรับคำสั่งนั้นจากไฟล์คลาสที่สร้างขึ้น แต่คำสั่งx=3;
นั้นไม่ถือว่า "ไม่สามารถเข้าถึงได้" ในแง่เทคนิคที่ระบุไว้ที่นี่
เหตุผลสำหรับการรักษาที่แตกต่างนี้คือการอนุญาตให้โปรแกรมเมอร์กำหนด "ตัวแปรธง" เช่น:
static final boolean DEBUG = false;
แล้วเขียนรหัสเช่น:
if (DEBUG) { x=3; }
แนวคิดคือควรจะสามารถเปลี่ยนค่าของ DEBUG จากเท็จเป็นจริงหรือจากจริงเป็นเท็จแล้วรวบรวมรหัสอย่างถูกต้องโดยไม่มีการเปลี่ยนแปลงอื่น ๆ ในข้อความของโปรแกรม
ทำไมคำสั่ง break แบบมีเงื่อนไขส่งผลให้เกิดข้อผิดพลาดของคอมไพเลอร์?
ตามที่ยกมาในกฎการเข้าถึงได้ของลูปห่วงในขณะที่ยังสามารถดำเนินการตามปกติถ้ามันมีคำสั่งหยุดพัก เนื่องจากกฎระเบียบสำหรับการเชื่อมของนั้นif
งบแล้วประโยคไม่ได้ใช้เงื่อนไขของการที่if
เข้าสู่การพิจารณาที่ทุกคนเช่นเงื่อนไขif
คำสั่งที่แล้วประโยคถือว่าเสมอสามารถเข้าถึงได้
หากbreak
สามารถเข้าถึงได้รหัสหลังจากลูปจะถือว่าสามารถเข้าถึงได้อีกครั้ง เนื่องจากไม่มีรหัสที่สามารถเข้าถึงได้ซึ่งส่งผลให้เกิดการยกเลิกอย่างกะทันหันหลังจากวนรอบวิธีการนี้จึงถือว่าสามารถดำเนินการตามปกติได้ดังนั้นคอมไพเลอร์จึงแจ้งว่าเป็นข้อผิดพลาด