Java'da bir goto ifadesi var mı?


259

Bu konuda kafam karıştı. Birçoğumuza Java'da herhangi bir goto ifadesi olmadığı söylendi.

Ama Java anahtar kelimelerden biri olduğunu buldum. Nerede kullanılabilir? Kullanılamıyorsa, neden Java'ya anahtar kelime olarak dahil edildi?


13
sadece bir kelime tavsiye: asla hiç goto kullanmayın
lostiniceland

16
Ve sonra '' Zarar Gördüğü Zararlı '' Zarar Gördüğü Zararlı '' ve “'' Zararlı Olarak Görülen Zararlıya“ Zarar Gördüğü Zararlı mı? ” VEEEEERY özyinelemeli, bu meme.
Chris Charabaruk

70
'git' her zaman kötüdür - 'git işi' veya 'git okulu' gibi;)
Andreas Dolk

24
Gerçek neden, "g ** o" kelimesinin çoğu programlama dilinde müstehcen olarak görülmesidir. Java tasarımcıları sadece masum genç programcıları yozlaşmış etkilerden koruyor. (:-))
Stephen C

25
Gitmeye karşı yapılan cadı avı, hayatımdaki en ağır anlardan bazılarını doğurdu. Ben insanlar fonksiyonlarında işlevselliği gizleyerek C kodu contort gördüm, çok iç içe döngüler saçma çıkış mantığı koymak ve aksi takdirde kod kod gözden eleştiren biri önlemek için aşırı mühendislik akla sadece her türlü yapmak. Bu kural, "birden fazla geri dönüşten kaçınmalısınız" kanunu ile birlikte, saçmalıklarla dolu. Goto'nun işleri daha az bakım gerektirdiği zamanlar vardır. Goto'nun işleri daha sürdürülebilir hale getirdiği zamanlar vardır. Bu cadı avının 80'lerde öleceğini umuyordum.

Yanıtlar:


200

Java'nın anahtar kelime listesi belirten gotoanahtar kelimeyi, ancak "kullanılmıyor" olarak işaretlenir.

Orijinal JVM'deydi ( @VitaliiFedorenko'nun cevabına bakınız ), ancak daha sonra kaldırıldı. Java'nın sonraki bir sürümüne eklenmesi durumunda büyük olasılıkla ayrılmış bir anahtar kelime olarak tutuldu.

Listede gotodeğilse ve daha sonra dile eklenirse, sözcüğü gototanımlayıcı olarak kullanan değişken kod (değişken adı, yöntem adı vb.) Bozulur. Ancak gotobir anahtar kelime olduğu için, bu tür kodlar günümüzde bile derlenmeyecektir ve mevcut kodu bozmadan daha sonra bir şeyler yapması mümkün olmaya devam etmektedir.


29
This was probably done in case it were to be added to a later version of Java.Aslında, ana neden biraz farklı (aşağıdaki cevabım bakınız)
Vitalii Fedorenko

2
Bu iyi ve ilginç bir bilgi, ancak neden hala ayrılmış bir anahtar kelime olduğunu açıklamıyor.
Thomas

@Thomas Neden ayrıldığını açıklamadınız mı? Bu bir anahtar kelime, bu yüzden şimdi kullanılamaz; daha sonra goto sorun yaratmadan canlanabilir. Ayrılmış bir kelime olmasaydı, artık goto tanıtıldığında kırılacak olan kod (int goto = 2;) üretmek için kullanılabilir.

230

James Gosling orijinal JVM'yi goto ifadeleri , ancak daha sonra bu özelliği gereksiz olarak kaldırdı. Ana neden gotogereksizdir, genellikle daha okunabilir ifadelerle (örneğin break/continue) veya bir yönteme bir parça kod çıkartılarak değiştirilebilmesidir.

Kaynak: James Gosling, Soru-Cevap oturumu


24
“... ya da bir yönteme bir kod parçası çıkararak” - bunun için uygun kuyruk çağrısının ortadan kaldırılmadan çok havalı olması gerekir.
Görünen Ad

45
Bazen bir akılcı kullanımıdır goto olan başka bir şey haline zorlayarak perforce yani şey ifade etmek en readyble ve net şekilde, daha az okunabilir .
Tekilleştirici

1
@Deduplicator Goto kullanımı, olabildiğince mantıklı, her zaman hataya açıktır.
Çelebi Murat

@Deduplicator C ++ 'da iyi uygulama olarak görülen goto'nun tek kullanımı mola / devam ile desteklenir.
Kış

2
Java'da ayrılmış bir anahtar kelime olmak harika çünkü insanların etiketlere "goto:" adını vermesini önlüyor.
Kış

147

Anahtar kelime var, ancak uygulanmıyor.

Düşünebileceğim goto kullanmanın tek iyi nedeni şudur:

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'da bunu şu şekilde yapabilirsiniz:

loops:
for (int i = 0; i < MAX_I; i++) {
    for (int j = 0; j < MAX_J; j++) {
        // do stuff
        break loops;
    }
}

1
@ Zoltán No - kodu ilk döngüden hemen önce etikete yönlendirir.
assylias

21
@assylias Pek değil. Etiket dış halkayı etiketler. Sonra break loops"denilen döngüden kopar" anlamına gelir loops. Belki geçmişe dönük olarak etiket için daha iyi bir isim olabilirdi outer.
jonnystoten

8
"Goto'yu kullanmanın tek iyi nedeni" Koşulsuz sonsuz döngü gerektiren hızlı ve kirli küçük programlar goto'yu büyük ölçüde kullanır. while (true) {... kullanmak }aşırıya kaçıyor. GOTO, yanlış kullanımları nedeniyle sık sık damgalanmaktadır, ancak boole değişmezleriyle yapılan gereksiz karşılaştırmaların GOTO'dan daha kötü olduğunu iddia ediyorum.
Alexander - Monica'yı eski

1
Döngüler etiketi döngülerden sonra olmamalı mı?
GC_

1
Kısa bir süre önce, bu etiketleme tekniğinin bir continue LABEL;ifade ile birlikte çok yararlı olduğunu keşfettim . Böylece bir dış yalan döngüsüne devam edebilirsiniz.
infotoni91


29

Yani bir gün dil tasarımcıları ihtiyacı hissederse kullanılabilirler.

Ayrıca, bu anahtar kelimelere (örn. C, C ++) sahip dillerden programcılar bunları yanlışlıkla kullanıyorsa, Java derleyicisi yararlı bir hata mesajı verebilir.

Ya da sadece programcıları goto kullanarak durdurmaktı :)


Java'daki eksik goto işlevselliği, goto kullanmamak için yeterli neden olmalıdır - bir anahtar kelime olarak ayırmaya gerek yoktur. Mantıktan sonra, her şey bir anahtar kelime olurdu, çünkü diğer diller ve / veya Java tasarımcıları tarafından gelecekte kullanılacaktır ...
stuXnet

1
Mantığımın her şeyin bir anahtar kelime olacağını ima ettiğini sanmıyorum. Birçok programlama dilinde, Java'da yararlı bir şekilde algılanabilen ve işlenebilen küçük bir anahtar kelime kümesi vardır. Java saklıdır gotove constC / C ++ mirasını yansıtır, ancak uygulanmazlar (ikincisinin uygulanmasıyla ilgili tartışmalar olmasına rağmen). Daha fazla gibi bir çift assertve enumbaşlangıçta belki ayrılmış, ancak değil, yapılmış, uygulanmış oldukları vermeliydim. Ama gez harika bir şey.
dave

19

İleride kullanılmak üzere ayrılmıştır (bakınız: Java Dili Anahtar Kelimeleri )

Const ve goto anahtar kelimeleri şu anda kullanılmasalar bile ayrılmıştır.

Sebebi neden Java hiçbir git ifadesi yoktur "bulunabilir Java Dil Çevre ":

Java'nın goto ifadesi yok. Çalışmalar, goto'nun sadece "çünkü" değil, daha sık kullanıldığını gösterdi. Goto'yu ortadan kaldırmak dilin basitleştirilmesine yol açtı - örneğin, bir gotonun for for ifadesinin ortasına etkileri hakkında herhangi bir kural yoktur. Yaklaşık 100.000 C kodu satırı üzerinde yapılan çalışmalar, goto ifadelerinin kabaca yüzde 90'ının yalnızca iç içe döngülerin kırılma etkisini elde etmek için kullanıldığını tespit etti. Yukarıda belirtildiği gibi, çok seviyeli kopma ve devam etme, goto ifadeleri ihtiyacının çoğunu ortadan kaldırır.


gotoayrılmış, ancak ileride kullanılmak üzere değil.
Lorne Marquis

17

Java'da "devam" etiketlerinin nasıl kullanılacağına bir örnek:

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

Sonuçlar:

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

10

gotoYapının, makine kodunda ve montaj dilinde programcıların programladığı günlerden kalma olduğunu anlamak önemlidir . Bu diller çok basit olduğu için (her talimatta olduğu gibi, sadece bir şey yapar), program kontrol akışı tamamen gotoifadelerle yapılır (ancak montaj dilinde bunlar atlama veya dal talimatları olarak adlandırılır ).

Şimdi, C dili oldukça düşük seviyeli olmasına rağmen, çok yüksek seviyeli bir montaj dili olarak düşünülebilir - C'deki her ifade ve işlev, montaj dili talimatlarına kolayca ayrılabilir. C, günümüzde bilgisayarları programlamak için ana dil olmasa da, gömülü sistemler gibi düşük seviyeli uygulamalarda hala yoğun olarak kullanılmaktadır. C'nin işlevi, montaj dilinin işlevini çok yakından yansıttığından, yalnızca gotoC'de bulunan mantıklıdır .

Java'nın C / C ++ 'ın bir evrimi olduğu açıktır. Java, C'nin birçok özelliğini paylaşır, ancak çok daha fazla ayrıntıyı özetler ve bu nedenle basitçe farklı şekilde yazılır. Java çok yüksek seviyeli bir dildir, bu yüzden gotoher biri için fonksiyonlar gibi daha yüksek seviyeli yapılar olduğunda ve döngüler program kontrol akışını yaparken olduğu gibi düşük seviyeli özelliklere sahip olmak gerekli değildir . gotoBir işlevdeyseniz ve başka bir işleve bir etikette etiket uyguladıysanız düşünün . Diğer işlev geri döndüğünde ne olur? Bu fikir saçma.

Bu, Java'nın gotoifadeyi neden içerdiğini , ancak derlemesine izin vermediğini mutlaka yanıtlamaz , ancak neden gotoilk etapta, alt düzey uygulamalarda kullanıldığını ve neden olması mantıklı olmadığını bilmek önemlidir. Java ile kullanılır.


msgstr "program kontrol akışı tamamen goto ile yapılır". Her zaman koşulsuz gitmez.
Peter Mortensen

C / C ++ 'da bir işlevden "goto" ile başka bir işlevdeki bir etikete atlamak da mümkün değildir. C / C ++ 'da Git, tek bir fonksiyon bloğu ile sınırlıdır.
user2328447

"sadece daha yüksek seviyeli yapılar zaman goto gibi düşük seviyeli özelliklere sahip olmak gerekli değildir" - "Gereklilik ve yeterlilik" unutmayın. Sadece "gerekli değil". Ve bu yüzden bir sebep yok. Sebebi nedir: "Yürütülebilir kod" atlamak istiyorsanız, Java bytecode ve bu nedenle "yürütülebilir" değilse, Assembler JMP, BNE ve daha fazlası için "yüksek seviye" yerine "Git" mantıklı. ;-)
reichhart

10

Hayır, gotokullanılmaz, ancak etiketleri tanımlayabilir ve bir döngüyü etikete kadar bırakabilirsiniz. Etiketi kullanabilir breakveya continuetakip edebilirsiniz . Böylece birden fazla döngü seviyesinden atlayabilirsiniz. Göz at öğretici .


9

Hayır, şükürler olsun ki goto Java'da yok.

gotoAnahtar kelime sadece ayrılmış, ancak (Aynı şey kullanılmaz const).


Ayrılmış olanın burada ne anlama geldiğini öğrenebilir miyim? Kodda goto ve const kullanmak iyi bir uygulama değilse, neden ayırırlar? Açıklayabilir misin?
Gopi

@Sri Kumar: bkz. @ Applechewer cevabı, var ama uygulanmadı.
Valentin Rocher 30'10

1
@Sri Kumar: Ayrılmış anahtar kelimeler değişken adı veya benzeri olarak kullanılmalarını engeller. Bu şekilde, bu anahtar kelimeler, başka türlü kullanabilecek eski kaynak kodunu bozmadan Java'nın gelecekteki sürümlerinde uygulanabilir.
Peter Di Cecco 30'10

8

Çünkü desteklenmiyor ve neden bir goto hiçbir şey yapmayan anahtar kelimeyi veyagoto ?

Her ne kadar etkili bir şekilde yapmak için break label;ve continue label;ifadeleri kullanabilirsiniz goto. Ama bunu tavsiye etmem.

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

10
-1 Neden goto adında bir değişkene veya yönteme sahip olmam gerekiyor?
Michael Borgwardt

4
Çünkü programlama alanında Java için geçerli olmayan bir anlamı vardır. Aynı zamanda değişken ismin kötü bir seçimidir.
pjp

Değişken bir 'baskı' ne için kullanılır? Bahsettiğiniz kelimeler değişkenlere veya anahtar kelimelere göre yöntem adlarına benzer.
pjp

3
-1: Her şeyden önce, Java'nın "goto" akış kontrol deyimini desteklememesi, hiçbir şey yapmayan "goto" anahtar kelimesinin olmasının nedeni olduğu anlamına gelmez. İkincisi, "goto" kötü bir değişken adı olabilir, ancak "goto" bir anahtar kelime olduğu için kullanamayacağımız mükemmel bir yöntem adı olabilir. Üçüncüsü, "mola etiketi" ve "etikete devam et" çok iyi bir nedenden ötürü mevcuttur, bu nedenle "tavsiye etmemek" çok yararlı değildir. Ve dördüncüsü, Sun "şu anda kullanılmadığını" söylediğinden, büyük olasılıkla bir zamanlar uygulamayı planladıkları, ancak başka türlü karar verdiklerinde anahtar kelimeden kurtulmak istemedikleri anlamına gelir.
Vojislav Stojkovic

2
@VojislavStojkovic Bu sadece çılgınca bir konuşma. 1) O ise hiçbir şey yapmaz neden bunu desteklemediği için olduğunu. JLS'ye göre 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.Bu, "Bunu kullanmıyoruz, bu yüzden bir C ++ arka planından geliyorsanız, onu hiç kullanmanıza izin vermeyeceğiz." Anlamına gelir. 2) gotokorkunç bir yöntem adıdır. Afedersiniz. 3) mola ve devam et önerilir, ancak burada kullanılan şekilde değildir . 4) "büyük olasılıkla" [alıntı gerekli].
corsiKa

7

Hayır, gotoayrılmış bir kelime olmasına rağmen Java'da kullanılmaz. Aynı şey için de geçerlidir const. Bunların her ikisi de büyük olasılıkla ayrılmış olmalarının nedeni olan C ++ 'da kullanılır; amaç büyük olasılıkla Java'ya geçiş yapan C ++ programcılarının kafasını karıştırmamak ve belki de bunları daha sonraki Java sürümlerinde kullanma seçeneğini korumaktı.


1
Umarım gotoen azından yakın gelecekte desteklenmez;)
Bozho

6
@Bozho: iyi, olabilir eski kötü "zararlı" Goto ile hiçbir ilgisi vardır bazı ustaca yeni özellik için kullanılabilir.
Michael Borgwardt

3

Goto'nun iyi huylu kullanımlarının çoğunu

  • dönüş

  • mola

  • etiketi kır

  • try-catch-nihayet içine atmak


5
Akış kontrolü için ASLA istisnalar kullanılmamalıdır
ChssPly76

13
İstisnalar vardır akış kontrolü için kullanılan, fakat sadece istisnai durumlar için kullanılmalıdır. Örneğin, C'deki goto kullanımlarından biri, özellikle temizliği içeriyorsa, hata işlemedir.
starblue

2
@starblue, kelimeleri ağzımdan çıkardın. Bir istisna Fırlatma olduğunu kontrol akışı. Aslında C'de, ilk olarak işleme koduna setjmp ayarladığınızdan ve istisnada longjmp () uygulayarak setjmp / longjmp aracılığıyla istisna işlemeyi bir şekilde temiz bir şekilde uygulayabilirsiniz.

Bir if kontrolü yapmak ve doğruysa yöntemin yarısını atlamak istiyorum. Gitmeden başka bir dev kullanmalıyım. Çok fazla parantezin kafa karışıklığı yarattığı için IMO oldukça çirkin
WVrock

1
@WVrock Deneyebilirsinizreturn
Andrew Lazarus

2

Belirtildiği gibi, gotoJava'da yok , ancak Sun'ın gotobir gün Java'ya eklemek istemesi durumunda anahtar kelime ayrıldı . Çok fazla kod kırmadan ekleyebilmek istediler, bu yüzden anahtar kelimeyi ayırdılar. Java 5 ile enumanahtar kelimeyi eklediklerini ve bu kadar kod kırmadığını unutmayın.

Java hiçbir olmasına rağmen goto, bazı yapıları vardır bazı kullanımlar için hangi tekabül gotoyani edememek, breakve continueadlandırılmış döngüler ile. Ayrıca, finallybir çeşit bükülmüş olarak düşünülebilir goto.


1

Aynı ada sahip değişkenlerin beyanlarını yasaklamak.

Örneğin int i = 0, goto;


3
Ama neden ? Neden bu beyanları vermemize izin verilmemeli?
ApproachingDarknessFish

1

Yapmadığınız şeylerden biri olarak kabul edilir, ancak muhtemelen geliştiriciler için karışıklığı önlemek için ayrılmış bir kelime olarak listelenmiştir.


1

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

Java'da bir goto ifadesi olmadığı söylendiğinde aldanıyorsunuz. Aslında, Java iki "kaynak" kodu katmanından oluşur.


5
bu, herhangi bir dilin bir gidişi olduğunu söylemek gibidir, çünkü hepsinin altındaki montaj kodunda koşulsuz bir dal vardır. Bayt kodunda goto olması, java'da bir goto olduğu anlamına gelmez, çünkü "java'da" "java dilinde" anlamına gelir ve bayt kodu bir kaynak katmanı değildir.

@ tgm1024, "Java'da" ayrıca "Java platformunda" olarak da yorumlanabilir. Java derleyicisinin Java bayt kodu üretmesi gerekir veya çıktı, Java platformu JVM'de çalışmaz. Örneğin C ++, derleme çıktısını belirtmez ve derleyici herhangi bir makine kodu (veya başka bir kod) üretmekte serbesttir. Java bayt kodu programlı uygulama "Java uygulaması" olarak adlandırılabilir, ancak makine kodu programlanmış uygulama "C ++ uygulaması" olarak adlandırılamaz.
Mikael Lindlöf

2
Java bayt kodunun ne olduğunu çok iyi biliyorum. İlk olarak 1996'da java kodlaması yapıyordum. JVM için java bayt kodu üreten başka dillere de sahip olabilirsiniz. Sizi düzelttiğim yer iki kaynak katmanı olduğu fikridir. Yok. Java kaynağınız var ve bu, java bayt koduna (JVM tarafından yürütülür) derlenir ve bu ek bir kaynak katmanı değildir. Bayt kodunda bir "goto" olması, java'da bir "goto" olduğu anlamına gelmez. Java, molaları adlandırdı ve devam ediyor adını verdi, ancak gitmedi.

@ tgm1024 Bir aşağı oyla uyandım :) Son yorumu yaptığınızdan ve kimlik bilgileriniz etkileyici olduğundan argümanı kaybettiğim kolayca görülebilir. İnşa ettiğim nokta, Java bayt kodu ile programlamanın çok mümkün olduğuydu. Sizi temin etmek için, bununla ilgili bir soru bile var: stackoverflow.com/questions/3150254/…
Mikael Lindlöf


1

Hayranı değilim goto genellikle , genellikle kodu daha az okunabilir yapar. Bununla birlikte, bu kuralın istisnaları olduğuna inanıyorum (özellikle söz konusu sözcükler ve ayrıştırıcılar söz konusu olduğunda!)

Tabii ki programınızı her zaman montajcı benzeri bir şeye çevirerek Kleene Normalform'a getirebilir ve daha sonra

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

(Yani temelde ikili kodunuzu yürüten bir VM yazıyorsunuz ... line yönerge işaretçisine karşılık gelir)

Bu, kullanılan koddan çok daha okunabilir gotodeğil mi?


Sonraki soru, "Python'da bir açıklama var mı?"
Mark K Cowan

0

Tabii ki anahtar kelime, ancak kaynak kodu düzeyinde kullanılmıyor.

Ancak jasmin veya bayt koduna dönüştürülen başka bir alt düzey dil kullanıyorsanız, "git"


-1

Çünkü Java dili bunu kullanmasa da, JVM bayt kodu kullanır.


7
O zaman dilin neden bir loadanahtar kelimesi yok?
ApproachingDarknessFish

3
@gribnit, bayt kodunda bir gota sahip olmak tek başına üst düzey ayrılmış kelimeler için bir şey ifade etmez.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.