Java'da goto anahtar sözcüğü için alternatif bir işlev nedir ?
Java'nın bir gotou olmadığı için.
Java'da goto anahtar sözcüğü için alternatif bir işlev nedir ?
Java'nın bir gotou olmadığı için.
Yanıtlar:
Etiketli bir BREAK ifadesi kullanabilirsiniz :
search:
for (i = 0; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length; j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search;
}
}
}
Ancak, düzgün tasarlanmış kodda GOTO işlevine ihtiyacınız olmamalıdır.
goto
Java'da kavramın doğrudan bir eşdeğeri yoktur . Bir klasikle yapabileceğiniz bazı şeyleri yapmanıza izin veren birkaç yapı vardır goto
.
break
Ve continue
ifadeleri bir döngü veya switch ifadesinde bir blok atlamaya izin verir.break <label>
rasgele bir bileşik ifadeden belirli bir yöntem (veya başlatıcı bloğu) içindeki herhangi bir seviyeye atlamanıza izin verir.continue <label>
, bir iç döngüden bir dış döngünün sonraki yinelemesine devam .return
.Bu Java yapılarının hiçbiri geriye doğru veya koddaki bir noktaya geçerli deyimle aynı iç içe geçme düzeyinde dallanmanıza izin vermez. Hepsi bir veya daha fazla yuvalama (kapsam) seviyesine continue
atlarlar ve hepsi (dışında ) aşağıya doğru atlarlar. Bu kısıtlama, eski BASIC, FORTRAN ve COBOL kod 2'de bulunan "spagetti kodu" sendromunun önlenmesine yardımcı olur .
1- İstisnaların en pahalı kısmı, istisna nesnesinin ve yığın izlemesinin fiili olarak oluşturulmasıdır. Gerçekten, gerçekten "normal" akış kontrolü için istisna işlemeyi kullanmanız gerekiyorsa, istisna nesnesini önceden tahsis edebilir / yeniden kullanabilir veya fillInStackTrace()
yöntemi geçersiz kılan özel bir istisna sınıfı oluşturabilirsiniz . Olumsuz tarafı, istisnanınprintStackTrace()
yöntemlerinin, onları aramanız gerekmesi durumunda size yararlı bilgiler vermemesidir.
2 - Spagetti kodu sendromu, yapılandırılmış programlama yaklaşımını doğurdu , burada mevcut dil yapılarını kullanımınızı sınırlandırdınız. Bu BASIC , Fortran ve COBOL'a uygulanabilir , ancak özen ve disiplin gerektiriyordu. goto
Tamamen kurtulmak pragmatik olarak daha iyi bir çözümdü. Bir dilde tutarsan, her zaman onu kötüye kullanacak bir palyaço vardır.
Sadece eğlence için, işte Java'da bir GOTO uygulaması.
Misal:
1 public class GotoDemo { 2 public static void main(String[] args) { 3 int i = 3; 4 System.out.println(i); 5 i = i - 1; 6 if (i >= 0) { 7 GotoFactory.getSharedInstance().getGoto().go(4); 8 } 9 10 try { 11 System.out.print("Hell"); 12 if (Math.random() > 0) throw new Exception(); 13 System.out.println("World!"); 14 } catch (Exception e) { 15 System.out.print("o "); 16 GotoFactory.getSharedInstance().getGoto().go(13); 17 } 18 } 19 }
Çalıştırmak:
$ java -cp bin:asm-3.1.jar GotoClassLoader GotoDemo 3 2 1 0 Hello World!
"Kullanmayın!" Eklemem gerekir mi?
Math.random()
0 döndürebilir.> =
HellWorld!o World!
çıktı bulup şaşkına döneceği eğlenceli bir Paskalya yumurtası . #AllBugsAreFeatures
Bazı yorum yapanlar ve downvoters bu olmadığını iddia ederken git , üretilen bayt kodu Java ifadeleri aşağıda gerçekten bu ifadeler gerçekten ekspres yapmak olduğunu göstermektedir git anlambilim.
Spesifik olarak, do {...} while(true);
ikinci örnekteki döngü, döngü koşulunu değerlendirmemek için Java derleyicileri tarafından optimize edilmiştir.
label: {
// do stuff
if (check) break label;
// do more stuff
}
Bayt kodunda:
2 iload_1 [check]
3 ifeq 6 // Jumping forward
6 ..
label: do {
// do stuff
if (check) continue label;
// do more stuff
break label;
} while(true);
Bayt kodunda:
2 iload_1 [check]
3 ifeq 9
6 goto 2 // Jumping backward
9 ..
continue label
geriye doğru sıçrama
// do stuff
ve öyleyse // do more stuff
, geriye doğru atlama continue label
"etkisine sahiptir"while(true)
(elbette ifadeden dolayı ). Bunun bu kadar kesin bir soru olduğunun farkında değildim ...
while(true)
Bir içine derleyici tarafından çevrilmiştir goto
baytkodu operasyonu. Gibi true
sabit değişmez olduğu, derleyici bu optimizasyona yapabilir ve bir şey değerlendirmek zorunda değildir. Öyleyse, benim örneğim gerçekten bir goto, geriye atlamak ...
Gerçekten goto ifadeleri gibi bir şey istiyorsanız, her zaman adlandırılmış bloklara geçmeyi deneyebilirsiniz.
Etiketi kırmak için blok kapsamında olmanız gerekir:
namedBlock: {
if (j==2) {
// this will take you to the label above
break namedBlock;
}
}
Neden gitmemeniz gerektiği konusunda size ders vermeyeceğim - bunun cevabını zaten bildiğinizi varsayıyorum.
public class TestLabel {
enum Label{LABEL1, LABEL2, LABEL3, LABEL4}
/**
* @param args
*/
public static void main(String[] args) {
Label label = Label.LABEL1;
while(true) {
switch(label){
case LABEL1:
print(label);
case LABEL2:
print(label);
label = Label.LABEL4;
continue;
case LABEL3:
print(label);
label = Label.LABEL1;
break;
case LABEL4:
print(label);
label = Label.LABEL3;
continue;
}
break;
}
}
public final static void print(Label label){
System.out.println(label);
}
StephenC şöyle yazıyor:
Klasik bir goto ile yapabileceğiniz bazı şeyleri yapmanızı sağlayan iki yapı vardır.
Bir tane daha...
Matt Wolfe şöyle yazıyor:
İnsanlar her zaman bir goto kullanmamaktan bahseder, ancak bence oldukça iyi bilinen ve kullanılan gerçekten iyi bir gerçek dünya kullanım durumu var .. Yani, bir işlevden dönmeden önce bazı kodları çalıştırdığınızdan emin olun .. Genellikle yayınlanması kilitler ya da ne değil, ama benim durumumda, dönüşten hemen önce bir molaya atlayabilmeyi çok isterim, böylece gerekli zorunlu temizliği yapabilirim.
try {
// do stuff
return result; // or break, etc.
}
finally {
// clean up before actually returning, even though the order looks wrong.
}
http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html
Nihayet bloğu, try bloğu çıktığında her zaman yürütülür. Bu, beklenmedik bir istisna meydana gelse bile nihayet bloğunun yürütülmesini sağlar. Ancak son olarak, istisna işlemeden daha fazlası için kullanışlıdır - programcının temizleme kodunun yanlışlıkla bir dönüş, devam etme veya kesme ile atlanmasını önlemesini sağlar. Hiçbir istisna beklenmese bile temizleme kodunu nihayet bloğuna koymak her zaman iyi bir uygulamadır.
Nihayet ile ilişkili aptalca mülakat sorusu şudur: Bir try {} bloğundan dönerseniz, ancak nihayetinde {} de bir dönüşünüz olursa, hangi değer döndürülür?
return
bir de finally
bloğu kötü bir fikirdir. (Ve bilgi kesinlikle gerekli olmasa bile, öğrenmek için merakı olmayan bir programcı beni endişelendiriyor ...)
En kolayı:
int label = 0;
loop:while(true) {
switch(state) {
case 0:
// Some code
state = 5;
break;
case 2:
// Some code
state = 4;
break;
...
default:
break loop;
}
}
Aşağıdaki kodu deneyin. Benim için çalışıyor.
for (int iTaksa = 1; iTaksa <=8; iTaksa++) { // 'Count 8 Loop is 8 Taksa
strTaksaStringStar[iCountTaksa] = strTaksaStringCount[iTaksa];
LabelEndTaksa_Exit : {
if (iCountTaksa == 1) { //If count is 6 then next it's 2
iCountTaksa = 2;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 2) { //If count is 2 then next it's 3
iCountTaksa = 3;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 3) { //If count is 3 then next it's 4
iCountTaksa = 4;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 4) { //If count is 4 then next it's 7
iCountTaksa = 7;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 7) { //If count is 7 then next it's 5
iCountTaksa = 5;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 5) { //If count is 5 then next it's 8
iCountTaksa = 8;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 8) { //If count is 8 then next it's 6
iCountTaksa = 6;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 6) { //If count is 6 then loop 1 as 1 2 3 4 7 5 8 6 --> 1
iCountTaksa = 1;
break LabelEndTaksa_Exit;
}
} //LabelEndTaksa_Exit : {
} // "for (int iTaksa = 1; iTaksa <=8; iTaksa++) {"
Java'da yoktur goto
, çünkü kodu yapılandırılmamış ve okunması belirsiz hale getirir . Ancak kullanabilirsiniz break
ve continue
olarak uygar şeklinde Goto onun sorunsuz.
ahead: {
System.out.println("Before break");
break ahead;
System.out.println("After Break"); // This won't execute
}
// After a line break ahead, the code flow starts from here, after the ahead block
System.out.println("After ahead");
Çıktı :
Before Break
After ahead
before: {
System.out.println("Continue");
continue before;
}
Bu , satır her yürütüldüğünde, kod akışı yeniden başlayacağı için sonsuz bir döngü ile sonuçlanacaktır .continue before
before
goto
Java kullanılabilir? Bence daha önemli olan burada yatıyor.