ฉันสับสนเกี่ยวกับเรื่องนี้ พวกเราส่วนใหญ่ได้รับการบอกว่าไม่มีคำสั่ง goto ใน Java
แต่ฉันพบว่ามันเป็นหนึ่งในคำหลักใน Java จะใช้ที่ไหน? หากไม่สามารถใช้งานได้ทำไมจึงรวมอยู่ใน Java เป็นคำหลัก
ฉันสับสนเกี่ยวกับเรื่องนี้ พวกเราส่วนใหญ่ได้รับการบอกว่าไม่มีคำสั่ง goto ใน Java
แต่ฉันพบว่ามันเป็นหนึ่งในคำหลักใน Java จะใช้ที่ไหน? หากไม่สามารถใช้งานได้ทำไมจึงรวมอยู่ใน Java เป็นคำหลัก
คำตอบ:
รายการ Java คำหลักที่ระบุgotoคำหลัก แต่ก็มีการทำเครื่องหมายว่า "ไม่ได้ใช้"
มันอยู่ใน JVM ดั้งเดิม (ดูคำตอบโดย @VitaliiFedorenko ) แต่ถูกลบออกแล้ว มันอาจจะถูกเก็บไว้เป็นคำหลักที่สงวนไว้ในกรณีที่มันจะถูกเพิ่มลงใน Java รุ่นที่ใหม่กว่า
หากgotoไม่ได้อยู่ในรายการและจะถูกเพิ่มเข้าไปในภาษาในภายหลังรหัสที่มีอยู่ซึ่งใช้คำgotoว่าเป็นตัวระบุ (ชื่อตัวแปรชื่อวิธีการ ฯลฯ ... ) จะแตก แต่เนื่องจากgotoเป็นคำหลักรหัสดังกล่าวจะไม่ได้รวบรวมในปัจจุบันและยังคงเป็นไปได้ที่จะทำให้มันทำอะไรบางอย่างในภายหลังโดยไม่ทำลายรหัสที่มีอยู่
This was probably done in case it were to be added to a later version of Java.อันที่จริงเหตุผลหลักคือแตกต่างกันเล็กน้อย (ดูคำตอบของฉันด้านล่าง)
James Gosling สร้าง JVM ดั้งเดิมด้วยการสนับสนุนgotoข้อความ แต่แล้วเขาก็ลบคุณสมบัตินี้โดยไม่จำเป็น เหตุผลหลักที่gotoไม่จำเป็นคือโดยปกติแล้วมันจะถูกแทนที่ด้วยคำสั่งที่อ่านได้ง่ายขึ้น (เช่นbreak/continue) หรือโดยการแยกส่วนของรหัสลงในวิธีการ
ที่มา: James Gosling, Q&A เซสชั่น
goto เป็นวิธีที่ readyble มากที่สุดและมีความชัดเจนในการแสดงบางสิ่งบางอย่างเพื่อบังคับให้มันเป็นอะไรอื่นเป็นอย่างเลี่ยงไม่พ้นที่อ่านได้น้อย
มีคำหลักอยู่ แต่ไม่มีการใช้งาน
เหตุผลที่ดีเพียงข้อเดียวที่ใช้ goto ที่ฉันคิดได้คือ:
for (int i = 0; i < MAX_I; i++) {
for (int j = 0; j < MAX_J; j++) {
// do stuff
goto outsideloops; // to break out of both loops
}
}
outsideloops:
ใน Java คุณสามารถทำสิ่งนี้ได้:
loops:
for (int i = 0; i < MAX_I; i++) {
for (int j = 0; j < MAX_J; j++) {
// do stuff
break loops;
}
}
break loopsหมายถึง "แยกออกจากวงที่เรียกว่าloops" outerบางทีในการหวนกลับเป็นชื่อที่ดีกว่าสำหรับฉลากที่อาจได้รับ
while (true) {... }เกินกำลัง GOTO ถูกตีตราบ่อยครั้งเนื่องจากการใช้งานที่ไม่เหมาะสม แต่ฉันยืนยันว่าการเปรียบเทียบตัวอักษรแบบบูลที่ไม่จำเป็นนั้นแย่กว่า GOTO
continue LABEL;คำสั่ง ดังนั้นคุณสามารถดำเนินการต่อวงโกหกด้านนอก
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
"คำหลัก const และ goto ถูกสงวนไว้แม้ว่าจะไม่ได้ใช้ก็ตาม"
ดังนั้นพวกเขาจึงสามารถใช้งานได้หนึ่งวันหากนักออกแบบภาษารู้สึกว่าต้องการ
นอกจากนี้หากโปรแกรมเมอร์จากภาษาที่มีคำหลักเหล่านี้ (เช่น C, C ++) ใช้คำเหล่านั้นโดยไม่ตั้งใจแล้วคอมไพเลอร์ Java สามารถให้ข้อความแสดงข้อผิดพลาดที่เป็นประโยชน์
หรือบางทีมันก็แค่หยุดโปรแกรมเมอร์ที่ใช้ goto :)
gotoและconstแสดงให้เห็นถึงมรดกของ C / C ++ แต่ยังคงไม่มีการใช้งาน (แม้ว่าจะมีการถกเถียงกันเกี่ยวกับการนำไปใช้หลัง) มีคู่ที่ชอบassertและenumไม่ได้จองไว้ในตอนแรก แต่น่าจะเป็นเพราะพวกเขาได้รับการปฏิบัติ แต่การเข้าใจถึงปัญหาหลังเหตุการณ์เป็นสิ่งมหัศจรรย์
สงวนไว้สำหรับการใช้งานในอนาคต (ดู: คำหลักภาษา Java )
คีย์เวิร์ด const และ goto ถูกสงวนไว้แม้ว่าจะไม่ได้ใช้ก็ตาม
เหตุผลที่ว่าทำไมไม่มีคำสั่งกลับไปข้างในชวาสามารถพบได้ใน " จาวาสิ่งแวดล้อมภาษา ":
Java ไม่มีคำสั่ง goto การศึกษาแสดงให้เห็นว่าข้ามไปใช้ (mis) ใช้บ่อยกว่าไม่เพียง "เพราะมันมี" การกำจัด goto นำไปสู่การทำให้ภาษาง่ายขึ้น - ไม่มีกฎเกี่ยวกับผลกระทบของการข้ามไปสู่คำสั่งกลางตัวอย่างเช่น การศึกษาเกี่ยวกับรหัส C ประมาณ 100,000 บรรทัดระบุว่าประมาณ 90 เปอร์เซ็นต์ของคำสั่ง goto นั้นใช้อย่างหมดจดเพื่อให้ได้ผลของการแยกออกจากลูปซ้อน ดังที่ได้กล่าวไว้ข้างต้นการแบ่งหลายระดับและดำเนินการลบความต้องการงบ goto ส่วนใหญ่ต่อไป
gotoสงวนไว้ แต่ไม่ใช่เพื่อการใช้ในอนาคต
ตัวอย่างของวิธีใช้ป้ายกำกับ "ทำต่อ" ใน Java คือ:
public class Label {
public static void main(String[] args) {
int temp = 0;
out: // label
for (int i = 0; i < 3; ++i) {
System.out.println("I am here");
for (int j = 0; j < 20; ++j) {
if(temp==0) {
System.out.println("j: " + j);
if (j == 1) {
temp = j;
continue out; // goto label "out"
}
}
}
}
System.out.println("temp = " + temp);
}
}
ผล:
I am here // i=0
j: 0
j: 1
I am here // i=1
I am here // i=2
temp = 1
สิ่งสำคัญคือต้องเข้าใจว่าการgotoสร้างนั้นเป็นส่วนที่เหลือจากวันที่โปรแกรมเมอร์เขียนโปรแกรมในรหัสเครื่องและภาษาแอสเซมบลี เนื่องจากภาษาเหล่านั้นเป็นภาษาพื้นฐาน (เช่นเดียวกับในแต่ละคำสั่งจะทำเพียงสิ่งเดียว ) ทำให้การควบคุมโปรแกรมเสร็จสมบูรณ์ด้วยgotoข้อความสั่ง (แต่ในภาษาแอสเซมบลีภาษาเหล่านี้จะเรียกว่าคำสั่งกระโดดหรือสาขา )
ตอนนี้ถึงแม้ว่าภาษา C จะค่อนข้างต่ำ แต่ก็สามารถคิดได้ว่าเป็นภาษาแอสเซมบลีระดับสูงมาก - แต่ละคำสั่งและฟังก์ชั่นใน C สามารถแบ่งออกเป็นคำแนะนำภาษาแอสเซมบลีได้ง่าย แม้ว่า C ไม่ใช่ภาษาหลักสำหรับโปรแกรมคอมพิวเตอร์ที่มีอยู่ทุกวันนี้ แต่ C ก็ยังคงใช้กันอย่างแพร่หลายในแอปพลิเคชันระดับต่ำเช่นระบบฝัง เนื่องจากฟังก์ชั่นของ C สะท้อนการทำงานของภาษาแอสเซมบลีอย่างใกล้ชิดจึงเหมาะสมที่gotoรวมอยู่ใน C เท่านั้น
เป็นที่ชัดเจนว่า Java เป็นวิวัฒนาการของ C / C ++ Java แบ่งปันคุณสมบัติมากมายจาก C แต่สรุปรายละเอียดได้มากมายและดังนั้นจึงถูกเขียนอย่างแตกต่างกัน Java เป็นภาษาระดับสูงมากดังนั้นจึงไม่จำเป็นต้องมีคุณสมบัติระดับต่ำเช่นgotoเมื่อโครงสร้างระดับสูงเช่นฟังก์ชันสำหรับแต่ละและในขณะที่ลูปทำโฟลว์ควบคุมโปรแกรม ลองนึกภาพถ้าคุณอยู่ในฟังก์ชั่นหนึ่งและทำgotoป้ายกำกับให้กับฟังก์ชั่นอื่น จะเกิดอะไรขึ้นเมื่อฟังก์ชันอื่นส่งคืน ความคิดนี้ไร้สาระ
นี่ไม่จำเป็นต้องตอบว่าทำไม Java จึงรวมgotoคำสั่งไว้ แต่จะไม่ยอมให้คอมไพล์ แต่สิ่งสำคัญคือต้องรู้ว่าทำไมgotoถูกใช้ตั้งแต่แรกในแอปพลิเคชันระดับต่ำกว่าและทำไมมันไม่สมเหตุสมผล ใช้ใน Java
ไม่ขอบคุณไม่มีgotoใน Java
gotoคำหลักที่สงวนไว้ แต่ไม่ได้ใช้ (เดียวกันจะไปสำหรับconst)
เนื่องจากไม่รองรับและทำไมคุณต้องการgotoคำหลักที่ไม่มีชื่อgotoหรือตัวแปร
แม้ว่าคุณจะสามารถใช้งานbreak label;และcontinue label;งบอย่างมีประสิทธิภาพทำในสิ่งที่gotoไม่ แต่ฉันจะไม่แนะนำที่นี่
public static void main(String [] args) {
boolean t = true;
first: {
second: {
third: {
System.out.println("Before the break");
if (t) {
break second;
}
System.out.println("Not executed");
}
System.out.println("Not executed - end of second block");
}
System.out.println("End of third block");
}
}
The keywords const and goto are reserved, even though they are not currently used. This may allow a Java compiler to produce better error messages if these C++ keywords incorrectly appear in programs.นี่หมายความว่า "เราไม่ได้ใช้งานดังนั้นถ้าคุณมาจากพื้นหลัง C ++ เราจะไม่ปล่อยให้คุณใช้เลย" 2) gotoเป็นชื่อวิธีที่แย่มาก ขอโทษ 3) แนะนำให้แบ่งและดำเนินการต่อ แต่ไม่แนะนำให้ใช้ในวิธีนี้ 4) "เป็นไปได้มากที่สุด"
ไม่gotoไม่ได้ใช้ใน Java แม้จะเป็นคำที่สงวนไว้ constเช่นเดียวกับที่เป็นจริงสำหรับ ทั้งสองนี้ใช้ใน C ++ ซึ่งอาจเป็นเหตุผลว่าทำไมพวกเขาจึงสงวนไว้ ความตั้งใจที่จะหลีกเลี่ยงความสับสนในการเขียนโปรแกรม C ++ เพื่อย้ายไปยัง Java และอาจเก็บตัวเลือกในการใช้พวกเขาในการแก้ไข Java ในภายหลัง
gotoจะไม่ได้รับการสนับสนุนในอนาคตอันใกล้อย่างน้อย;)
โปรดทราบว่าคุณสามารถแทนที่การใช้ goto ที่เป็นพิษเป็นภัยส่วนใหญ่ได้
กลับ
หยุดพัก
ทำลายฉลาก
ลองเข้าไปจับในที่สุด
return
ดังที่ได้กล่าวไว้แล้วว่าไม่มีgotoใน Java แต่คำหลักนั้นถูกสงวนไว้ในกรณีที่ Sun รู้สึกอยากgotoจะเพิ่มใน Java หนึ่งวัน พวกเขาต้องการที่จะเพิ่มได้โดยไม่ทำลายรหัสมากเกินไปดังนั้นพวกเขาจึงสงวนคำหลักไว้ โปรดทราบว่าด้วย Java 5 พวกเขาเพิ่มenumคำหลักและมันก็ไม่ได้ทำลายรหัสมากเช่นกัน
แม้ว่า Java จะไม่มีgotoแต่ก็มีโครงสร้างบางอย่างที่สอดคล้องกับประเพณีบางอย่างของgotoความสามารถในการbreakและcontinueมีลูปที่มีชื่อ นอกจากนี้ยังอาจจะคิดว่าเป็นชนิดของการบิดfinallygoto
ห้ามการประกาศตัวแปรที่มีชื่อเหมือนกัน
เช่น
int i = 0, goto;
มันถือว่าเป็นหนึ่งในสิ่งที่คุณห้ามทำ แต่อาจถูกระบุว่าเป็นคำที่สงวนไว้เพื่อหลีกเลี่ยงความสับสนสำหรับผู้พัฒนา
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.goto
หากคุณได้รับแจ้งว่าไม่มีคำสั่ง goto ใน Java คุณจะถูกหลอก ที่จริงแล้ว Java นั้นประกอบด้วยโค้ด 'ซอร์ส' สองชั้น
ดูลิงค์ต่อไปนี้จะแสดงคำที่สงวนไว้ทั้งหมดของ Java และบอกคุณว่ามีเวอร์ชันใดบ้างที่เพิ่มเข้ามา
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
goto ถูกจองถึงแม้ว่ามันจะไม่ได้ใช้ในปัจจุบันก็ตามอย่าพูดเลยว่า :)
ฉันไม่ได้เป็นแฟนของgotoทั้งสองเพราะมันมักจะทำให้อ่านรหัสน้อย อย่างไรก็ตามฉันเชื่อว่ามีข้อยกเว้นสำหรับกฎนั้น (โดยเฉพาะเมื่อพูดถึง lexers และ parsers!)
แน่นอนคุณสามารถนำโปรแกรมของคุณเข้าสู่ Kleene Normalform โดยการแปลเป็นแอสเซมเบลอร์จากนั้นเขียนสิ่งที่ชอบ
int line = 1;
boolean running = true;
while(running)
{
switch(line++)
{
case 1: /* line 1 */
break;
case 2: /* line 2 */
break;
...
case 42: line = 1337; // goto 1337
break;
...
default: running = false;
break;
}
}
(โดยทั่วไปคุณเขียน VM ที่รันรหัสไบนารี่ของคุณ ... ซึ่งlineตรงกับตัวชี้คำสั่ง)
มันอ่านได้ง่ายกว่าโค้ดที่ใช้gotoใช่ไหม
แน่นอนมันเป็นคำหลัก แต่ไม่ได้ใช้กับระดับของซอร์สโค้ด
แต่ถ้าคุณใช้ jasmin หรือภาษาระดับต่ำกว่าอื่นซึ่งเปลี่ยนเป็น bytecode แล้ว "goto" จะมี
เนื่องจากถึงแม้ว่าภาษา Java ไม่ได้ใช้งาน JVM bytecode ก็ทำเช่นนั้น
loadคำค้นหา
gotoไม่ได้อยู่ในJava
คุณต้องใช้ GOTO แต่มันไม่ทำงานอย่างถูกต้องในคำ java คีย์มันไม่ได้ใช้ http://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
public static void main(String[] args) {
GOTO me;
//code;
me:
//code;
}
}