ฉันสับสนเกี่ยวกับเรื่องนี้ พวกเราส่วนใหญ่ได้รับการบอกว่าไม่มีคำสั่ง 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
มีลูปที่มีชื่อ นอกจากนี้ยังอาจจะคิดว่าเป็นชนิดของการบิดfinally
goto
ห้ามการประกาศตัวแปรที่มีชื่อเหมือนกัน
เช่น
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;
}
}