Apakah ada pernyataan goto di Jawa?

259

Saya bingung tentang ini. Sebagian besar dari kita telah diberitahu bahwa tidak ada pernyataan goto di Jawa.

Tetapi saya menemukan bahwa itu adalah salah satu kata kunci di Jawa. Di mana bisa digunakan? Jika tidak dapat digunakan, lalu mengapa itu dimasukkan di Jawa sebagai kata kunci?

Venkat
sumber
13
hanya kata nasihat: tidak pernah menggunakan goto
lostiniceland
16
Dan kemudian ada "'Ke Pernyataan Dianggap Berbahaya' Dianggap Berbahaya", dan "'" Ke Pernyataan Dianggap Berbahaya "Dianggap Berbahaya' Dianggap Berbahaya?" VEEEEERY rekursif, meme ini.
Chris Charabaruk
70
'goto' selalu jahat - seperti dalam 'pekerjaan goto' atau 'sekolah goto';)
Andreas Dolk
24
Alasan sebenarnya adalah bahwa kata "g ** o" dianggap cabul di sebagian besar bahasa pemrograman. Desainer Java hanya melindungi programmer muda yang tidak bersalah dari pengaruh yang merusak. (:-))
Stephen C
25
Perburuan penyihir melawan goto telah menelurkan beberapa momen paling memberatkan dalam hidupku. Saya telah melihat orang-orang memutarbalikkan kode C dengan menyembunyikan fungsionalitas dalam fungsi-fungsi, menempatkan logika keluar yang tidak masuk akal dalam loop multi-bersarang, dan sebaliknya melakukan setiap bentuk rekayasa berlebihan yang HANYA untuk menghindari seseorang mengkritik kode mereka dalam tinjauan kode. Aturan ini, bersama dengan canard "kamu harus menghindari pengembalian berganda", tidak masuk akal. Ada saat-saat goto membuat hal-hal menjadi kurang terpelihara. Ada saat-saat goto membuat hal-hal lebih dapat dipertahankan. Aku sangat berharap perburuan penyihir ini akan mati di tahun 80-an.

Jawaban:

200

Daftar kata kunci Java menentukan gotokata kunci, tetapi ditandai sebagai "tidak digunakan".

Itu di JVM asli (lihat jawaban oleh @VitaliiFedorenko ), tetapi kemudian dihapus. Itu mungkin disimpan sebagai kata kunci yang dicadangkan jika itu akan ditambahkan ke versi Java yang lebih baru.

Jika gototidak ada dalam daftar, dan itu akan ditambahkan ke bahasa nanti, kode yang ada yang menggunakan kata gotosebagai pengidentifikasi (nama variabel, nama metode, dll ...) akan rusak. Tetapi karena gotomerupakan kata kunci, kode tersebut bahkan tidak dapat dikompilasi di masa sekarang, dan tetap memungkinkan untuk membuatnya benar-benar melakukan sesuatu di kemudian hari, tanpa melanggar kode yang ada.

Thomas
sumber
29
This was probably done in case it were to be added to a later version of Java.Sebenarnya, alasan utamanya sedikit berbeda (lihat jawaban saya di bawah)
Vitalii Fedorenko
2
Itu informasi yang bagus dan menarik, tetapi tidak menjelaskan mengapa itu masih kata kunci yang dipesan.
Thomas
@ Thomas Apakah Anda tidak menjelaskan mengapa itu disediakan? Itu kata kunci, jadi tidak bisa digunakan sekarang; nanti goto bisa hidup tanpa menimbulkan masalah. Jika itu bukan kata yang dilindungi undang-undang, kata itu dapat digunakan sekarang untuk menghasilkan kode (int goto = 2;) yang akan pecah jika goto diperkenalkan.
230

James Gosling menciptakan JVM asli dengan dukungan gotopernyataan, tetapi kemudian ia menghapus fitur ini sebagai tidak perlu. Alasan utama gotoyang tidak perlu adalah bahwa biasanya dapat diganti dengan pernyataan yang lebih mudah dibaca (seperti break/continue) atau dengan mengekstraksi sepotong kode ke dalam metode.

Sumber: James Gosling, sesi tanya jawab

Vitalii Fedorenko
sumber
24
"... atau dengan mengekstraksi sepotong kode ke dalam metode" - yang pasti sangat keren tanpa eliminasi panggilan ekor yang tepat.
Nama Tampilan
45
Kadang-kadang, penggunaan yang bijaksana goto adalah cara yang paling siap dan jelas untuk mengekspresikan sesuatu, jadi memaksanya ke hal lain menjadi kurang mudah dibaca .
Deduplicator
1
@Deduplicator Penggunaan goto, meskipun bijaksana, selalu rentan terhadap kesalahan.
Çelebi Murat
@Deduplicator Satu-satunya penggunaan goto yang dianggap sebagai praktik yang baik di C ++ didukung oleh break / continue.
Musim dingin
2
Menjadi kata kunci yang dilindungi undang-undang di Jawa sangat bagus karena mencegah orang memberi label "goto:".
Musim dingin
147

Kata kunci ada, tetapi tidak diterapkan.

Satu-satunya alasan bagus untuk menggunakan goto yang dapat saya pikirkan adalah ini:

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:

Di Jawa Anda dapat melakukan ini seperti ini:

loops:
for (int i = 0; i < MAX_I; i++) {
    for (int j = 0; j < MAX_J; j++) {
        // do stuff
        break loops;
    }
}
Jonnystoten
sumber
1
@ Zoltán Tidak - pengalihan kode ke label, tepat sebelum loop pertama.
assylias
21
@assylias Yah, tidak cukup. Label memberi label loop luar. Kemudian break loopsberarti "keluar dari loop yang disebut loops". Mungkin dalam retrospeksi nama yang lebih baik untuk label mungkin outer.
jonnystoten
8
"Satu-satunya alasan bagus untuk menggunakan goto" Program kecil yang cepat dan kotor yang memerlukan loop tak terbatas tanpa syarat memanfaatkan goto. Menggunakan while (true) {... }berlebihan. GOTO sering distigmatisasi karena penggunaannya yang tidak tepat, tetapi saya berpendapat bahwa perbandingan yang tidak perlu dengan literal boolean lebih buruk daripada GOTO.
Alexander - Reinstate Monica
1
Bukankah seharusnya label loop setelah loop?
GC_
1
Baru-baru ini saya menemukan, bahwa teknik pelabelan ini juga sangat berguna dalam kombinasi dengan continue LABEL;pernyataan. Dengan demikian Anda dapat melanjutkan lingkaran berbaring luar.
infotoni91
43

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html

"Kata kunci const dan goto dicadangkan, meskipun saat ini tidak digunakan."

Isaac E
sumber
12
"unsigned" bahkan tidak ada! (menghela napas)
Matthieu
Masuk akal, karena semua tipe primitif di Jawa ditandatangani.
mwieczorek
1
@mwieczorek Tidak semua. "char" adalah tipe primitif dan tidak bertanda tangan.
Sergey Krivenkov
29

Jadi mereka bisa digunakan suatu hari jika perancang bahasa merasa perlu.

Juga, jika programmer dari bahasa yang memiliki kata kunci ini (mis. C, C ++) menggunakannya secara tidak sengaja, maka kompiler Java dapat memberikan pesan kesalahan yang berguna.

Atau mungkin itu hanya untuk menghentikan programmer menggunakan goto :)

dave
sumber
Fungsi goto yang hilang di Jawa harus menjadi alasan yang cukup untuk tidak menggunakan goto - tidak perlu memesannya sebagai kata kunci. Mengikuti Anda dengan logika, semuanya akan menjadi kata kunci, karena digunakan oleh bahasa lain dan / atau desainer Java BISA menggunakannya di masa depan ...
stuXnet
1
Saya tidak berpikir bahwa logika saya menyiratkan semuanya akan menjadi kata kunci. Ada satu set kata kunci kecil yang digunakan di banyak bahasa pemrograman yang berguna dapat dideteksi dan ditangani di Jawa. Java mencadangkan gotodan constmencerminkan warisan C / C ++ tetapi mereka tetap tidak diterapkan (meskipun ada perdebatan tentang penerapan yang terakhir). Pasangan lebih suka assertdan enumawalnya tidak dicadangkan, tetapi mungkin seharusnya, mengingat mereka telah diterapkan. Tapi melihat ke belakang adalah hal yang luar biasa.
dave
19

Mereka dicadangkan untuk penggunaan di masa mendatang (lihat: Kata Kunci Bahasa Jawa )

Kata kunci const dan goto dicadangkan, meskipun saat ini tidak digunakan.

Alasan mengapa tidak ada pernyataan goto di Jawa dapat ditemukan di " Lingkungan Bahasa Jawa ":

Java tidak memiliki pernyataan goto. Studi menggambarkan bahwa goto (salah) digunakan lebih sering daripada tidak hanya "karena ada". Menghilangkan goto menyebabkan penyederhanaan bahasa - tidak ada aturan tentang efek goto ke tengah-tengah pernyataan, misalnya. Studi pada sekitar 100.000 baris kode C menentukan bahwa sekitar 90 persen dari pernyataan goto digunakan murni untuk mendapatkan efek dari keluar dari loop bersarang. Seperti disebutkan di atas, multi-level istirahat dan terus menghapus sebagian besar kebutuhan untuk pernyataan goto.

Heinzi
sumber
gotodicadangkan, tetapi tidak untuk digunakan di masa depan.
Marquis of Lorne
17

Contoh cara menggunakan label "terus" di Jawa adalah:

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);
    }
}

Hasil:

I am here // i=0
j: 0
j: 1
I am here // i=1
I am here // i=2
temp = 1
andrew
sumber
10

Penting untuk dipahami bahwa gotokonstruk tersebut merupakan sisa dari hari-hari yang diprogram oleh programmer dalam kode mesin dan bahasa rakitan. Karena bahasa-bahasa itu sangat mendasar (seperti dalam, setiap instruksi hanya melakukan satu hal), aliran kontrol program dilakukan sepenuhnya dengan gotopernyataan (tetapi dalam bahasa assembly, ini disebut sebagai instruksi lompat atau cabang ).

Sekarang, meskipun bahasa C adalah level yang cukup rendah, ia dapat dianggap sebagai bahasa assembly tingkat sangat tinggi - setiap pernyataan dan fungsi dalam C dapat dengan mudah dipecah menjadi instruksi bahasa assembly. Meskipun C bukan bahasa utama untuk memprogram komputer dengan saat ini, masih banyak digunakan dalam aplikasi tingkat rendah, seperti sistem embedded. Karena fungsi C sangat dekat dengan fungsi bahasa assembly, maka masuk akal jika gotodimasukkan dalam C.

Jelas bahwa Java adalah evolusi C / C ++. Java berbagi banyak fitur dari C, tetapi abstrak lebih banyak detailnya, dan karenanya ditulis secara berbeda. Java adalah bahasa tingkat sangat tinggi, jadi tidak perlu memiliki fitur tingkat rendah seperti gotoketika lebih banyak konstruksi tingkat tinggi seperti fungsi, untuk, untuk masing-masing, dan sementara loop melakukan aliran kontrol program. Bayangkan jika Anda berada dalam satu fungsi dan melakukan gotolabel ke fungsi lain. Apa yang akan terjadi ketika fungsi lainnya kembali? Gagasan ini tidak masuk akal.

Ini tidak selalu menjawab mengapa Java menyertakan gotopernyataan itu tetapi tidak akan membiarkannya dikompilasi, tetapi penting untuk mengetahui mengapa gotopernah digunakan di tempat pertama, dalam aplikasi tingkat rendah, dan mengapa itu tidak masuk akal untuk menjadi digunakan di Jawa.

Michael P di NCSU
sumber
msgstr "aliran kontrol program dilakukan sepenuhnya dengan goto". Yah, goto tidak selalu tanpa syarat.
Peter Mortensen
Melompat dengan "goto" dari satu fungsi ke label di fungsi lain juga tidak mungkin di C / C ++. Goto di C / C ++ terbatas pada blok fungsi tunggal.
user2328447
"itu tidak perlu untuk memiliki fitur tingkat rendah seperti kebagian ketika lebih banyak konstruksi tingkat tinggi" - ingat "Kebutuhan dan kecukupan". Hanya saja "tidak perlu". Dan dengan demikian tidak ada alasan. Apa alasannya: "Goto" sebagai pengganti "level tinggi" untuk JMP Assembler, BNE, dan lainnya adalah masuk akal jika Anda ingin beralih ke "kode yang dapat dieksekusi" tetapi Java adalah bytecode dan dengan demikian tidak "dapat dieksekusi". ;-)
reichhart
10

Tidak, gototidak digunakan, tetapi Anda dapat mendefinisikan label dan membiarkan perulangan ke label. Anda dapat menggunakan breakatau continuemengikuti label. Jadi Anda bisa melompat lebih dari satu level loop. Lihat tutorialnya .

Arne Burmeister
sumber
9

Tidak, untungnya, tidak ada gotodi Jawa.

Kata gotokunci hanya disediakan, tetapi tidak digunakan (berlaku untuk const).

Bozho
sumber
Bolehkah saya tahu Apa yang dimaksudkan orang yang dipesan di sini? Jika menggunakan goto dan const dalam kode bukan praktik yang baik, mengapa mereka memesannya? Bisakah Anda jelaskan?
Gopi
@Sri Kumar: lihat jawaban @ applechewer, itu ada tetapi tidak diterapkan.
Valentin Rocher
1
@Sri Kumar: Kata kunci yang dicadangkan mencegahnya digunakan sebagai nama variabel atau serupa. Dengan cara ini, kata kunci ini dapat diimplementasikan di versi Java yang akan datang tanpa melanggar kode sumber lama yang seharusnya dapat menggunakannya.
Peter Di Cecco
8

Karena tidak didukung dan mengapa Anda ingin gotokata kunci yang tidak melakukan apa pun atau variabel bernama goto?

Meskipun Anda dapat menggunakan break label;dan continue label;pernyataan untuk secara efektif melakukan apa yang gotodilakukan. Tapi saya tidak akan merekomendasikannya.

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");
     }
}
pjp
sumber
10
-1 Mengapa saya tidak diizinkan memiliki variabel atau metode bernama goto?
Michael Borgwardt
4
Karena memiliki makna di tanah pemrograman yang tidak berlaku untuk Java. Ini juga pilihan nama variabel yang buruk.
pjp
Untuk apa variabel 'cetak' digunakan? Kata-kata yang telah Anda sebutkan lebih mirip nama metode daripada variabel atau kata kunci.
pjp
3
-1: Pertama-tama, hanya karena Java tidak mendukung pernyataan kontrol aliran "goto", tidak berarti itu alasan mengapa ia memiliki kata kunci "goto" yang tidak melakukan apa-apa. Kedua, "goto" mungkin nama variabel yang buruk, tetapi itu bisa menjadi nama metode yang sangat baik, yang tidak dapat kita gunakan karena "goto" adalah kata kunci. Ketiga, "break label" dan "continue label" ada karena alasan yang sangat bagus, jadi "tidak merekomendasikannya" tidak terlalu berguna. Dan keempat, karena Sun mengatakan itu "belum digunakan", kemungkinan besar berarti bahwa mereka pernah berencana untuk mengimplementasikan, tetapi tidak ingin menyingkirkan kata kunci ketika mereka memutuskan sebaliknya.
Vojislav Stojkovic
2
@ VojislavStojkovic Itu hanya pembicaraan gila. 1) Itu adalah mengapa tidak apa-apa karena tidak mendukungnya. Menurut JLS 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.Ini berarti "Kami tidak menggunakannya, jadi jika Anda berasal dari latar belakang C ++ kami tidak akan membiarkan Anda menggunakannya sama sekali.". 2) gotoadalah nama metode yang mengerikan. Maaf. 3) istirahat dan lanjutkan disarankan, tetapi tidak dengan cara yang digunakan di sini . 4) "kemungkinan besar" [rujukan?].
corsiKa
7

Tidak, gototidak digunakan di Jawa, meskipun kata yang dilindungi undang-undang. Hal yang sama berlaku untuk const. Keduanya digunakan dalam C ++, yang mungkin merupakan alasan mengapa mereka dicadangkan; maksudnya mungkin untuk menghindari programmer C ++ yang bingung bermigrasi ke Jawa, dan mungkin juga untuk mempertahankan pilihan untuk menggunakannya di revisi Java yang lebih baru.

Michael Borgwardt
sumber
1
Saya benar-benar berharap gototidak didukung dalam waktu dekat setidaknya;)
Bozho
6
@ Bozho: yah, itu bisa digunakan untuk beberapa fitur baru yang cerdik yang sama sekali tidak ada hubungannya dengan goto "berbahaya" lama yang buruk.
Michael Borgwardt
3

Perhatikan bahwa Anda dapat mengganti sebagian besar penggunaan jinak oleh

  • kembali

  • istirahat

  • label istirahat

  • lempar ke dalam coba-tangkap-akhirnya

starblue
sumber
5
Pengecualian harus TIDAK PERNAH digunakan untuk kontrol aliran
ChssPly76
13
Pengecualian yang digunakan untuk kontrol aliran, tetapi harus digunakan hanya untuk kasus luar biasa. Sebagai contoh, salah satu penggunaan goto di C adalah penanganan kesalahan, terutama jika itu melibatkan pembersihan.
starblue
2
@ Starblue, Anda mengeluarkan kata-kata dari mulut saya. Melempar pengecualian adalah aliran kontrol. Pada C, pada kenyataannya, Anda bisa menerapkan penanganan pengecualian melalui setjmp / longjmp dengan memastikan Anda mengatur setjmp terlebih dahulu ke kode penanganan dan mengeksekusi longjmp () dengan pengecualian.
Saya ingin melakukan jika memeriksa dan melewatkan setengah dari metode jika benar. Tanpa pergi ke saya harus menggunakan raksasa lain. IMO itu sangat jelek karena terlalu banyak paranthesis menciptakan kebingungan
WVrock
1
@WVrock Anda bisa mencobareturn
Andrew Lazarus
2

Seperti yang ditunjukkan, tidak ada gotodi Jawa, tetapi kata kunci dicadangkan jika Sun ingin menambahkan gotoke Jawa suatu hari. Mereka ingin dapat menambahkannya tanpa melanggar terlalu banyak kode, jadi mereka memesan kata kunci. Perhatikan bahwa dengan Java 5 mereka menambahkan enumkata kunci dan tidak merusak kode sebanyak itu.

Meskipun Java tidak memiliki goto, ia memiliki beberapa konstruksi yang sesuai dengan beberapa penggunaan goto, yaitu mampu breakdan continuedengan loop bernama. Juga, finallydapat dianggap sebagai semacam bengkok goto.

Thomas Pornin
sumber
1

Untuk melarang deklarasi variabel dengan nama yang sama.

misalnya int i = 0, goto;

Karl
sumber
3
Tapi mengapa ? Mengapa kita tidak boleh membuat deklarasi ini?
ApproachingDarknessFish
1

Ini sangat dianggap sebagai salah satu hal yang Tidak Anda Lakukan, tetapi mungkin terdaftar sebagai kata yang dilindungi undang-undang untuk menghindari kebingungan bagi pengembang.

Dean J
sumber
1

http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.goto

Jika Anda telah diberitahu bahwa tidak ada pernyataan goto di Jawa Anda telah tertipu. Memang, Java terdiri dari dua lapisan kode 'sumber'.

Mikael Lindlöf
sumber
5
itu seperti mengatakan bahwa bahasa apa pun memiliki goto karena ada cabang tanpa syarat dalam kode assembly di bawah itu semua. Memiliki goto dalam kode byte tidak berarti bahwa ada goto di java karena "di java" berarti "Dalam bahasa java", dan kode byte bukan lapisan sumber.
@ tgm1024, "dalam Java" juga dapat diartikan sebagai "dalam platform Java". Java compiler perlu menghasilkan bytecode atau output Java tidak akan berfungsi di platform Java JVM. C ++, misalnya, tidak menentukan output kompilasi dan kompiler bebas untuk menghasilkan segala bentuk kode mesin (atau kode lainnya). Aplikasi yang diprogram bytecode Java dapat disebut "aplikasi Java" tetapi aplikasi yang diprogram kode mesin tidak dapat disebut "aplikasi C ++".
Mikael Lindlöf
2
Saya tahu betul apa itu bytecode java. Saya pertama kali coding di java pada tahun 1996. Dan Anda dapat memiliki bahasa lain menghasilkan bytecode java untuk JVM. Di mana saya mengoreksi Anda adalah gagasan bahwa ada dua lapisan sumber. Tidak ada. Anda memiliki sumber java dan ini dikompilasi ke kode byte java (dijalankan oleh JVM) dan ini bukan lapisan sumber tambahan. Hanya karena ada "goto" dalam kode byte tidak berarti ada "goto" di java. Java telah memberi nama istirahat dan bernama terus, tetapi tidak ada goto.
@ tgm1024 Saya dibangunkan oleh downvote :) Tampaknya dengan mudah saya kehilangan argumen sejak Anda membuat komentar terakhir dan kredensial Anda mengesankan. Maksud saya, yang sedang saya kembangkan, adalah bahwa sangat mungkin untuk memprogram dengan bytecode Java. Untuk meyakinkan Anda, bahkan ada pertanyaan tentang itu: stackoverflow.com/questions/3150254/…
Mikael Lindlöf
1

Saya juga bukan penggemar goto, karena biasanya membuat kode lebih mudah dibaca. Namun saya percaya bahwa ada pengecualian untuk aturan itu (terutama ketika menyangkut lexers dan parser!)

Tentu saja Anda selalu dapat membawa program Anda ke Kleene Normalform dengan menerjemahkannya menjadi sesuatu yang seperti assembler dan kemudian menulis sesuatu seperti

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;
    }
}

(Jadi Anda pada dasarnya menulis VM yang mengeksekusi kode biner Anda ... di mana linesesuai dengan pointer instruksi)

Itu jauh lebih mudah dibaca daripada kode yang digunakan goto, bukan?

Viktor Engelmann
sumber
Pertanyaan berikutnya, "Apakah ada pernyataan beralih dengan Python"
Mark K Cowan
0

Tentu saja itu kata kunci, tetapi tidak digunakan pada level kode sumber.

Tetapi jika Anda menggunakan jasmin atau bahasa tingkat rendah lainnya, yang diubah menjadi bytecode, maka "goto" ada

pengguna1722245
sumber
-1

Karena meskipun bahasa Java tidak menggunakannya, bytecode JVM melakukannya.

gribnit
sumber
7
Lalu mengapa bahasa itu tidak memiliki loadkata kunci?
ApproachingDarknessFish
3
@ gribnit, memiliki goto dalam bytecode tidak dengan sendirinya berarti apa-apa untuk kata-kata yang dicadangkan tingkat atas.