Що таке альтернативна функція для ключового слова goto в Java?
Оскільки Java не має goto.
Що таке альтернативна функція для ключового слова goto в Java?
Оскільки Java не має goto.
Відповіді:
Ви можете використати позначений BREAK вираз:
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;
}
}
}
Однак у правильно розробленому коді вам не потрібна функція GOTO.
У goto
Java немає прямого еквівалента концепції. Є кілька конструкцій , які дозволяють зробити деякі з речей , які ви можете зробити з класичним goto
.
break
and continue
дозволяють вам вистрибнути з блоку в циклі або переключити оператор.break <label>
дозволяє вискакувати з довільного складеного оператора на будь-який рівень у межах заданого методу (або блоку ініціалізації).continue <label>
продовжити наступну ітерацію зовнішнього циклу з внутрішнього циклу.return
.Жодна з цих конструкцій Java не дозволяє розгалужуватись назад або до точки в коді на тому ж рівні вкладеності, що і поточний оператор. Всі вони вистрибують з одного або декількох рівнів вкладеності (розмаху), і всі (крім continue
) стрибають вниз. Це обмеження допомагає уникнути синдрому "коду спагетті", властивого старому коду BASIC, FORTRAN та COBOL 2 .
1- Найдорожчою частиною винятків є фактичне створення об'єкта виключення та його стека. Якщо вам дійсно, дійсно потрібно використовувати обробку винятків для "звичайного" керування потоком, ви можете або перерозподілити / повторно використати об'єкт виключення, або створити власний клас винятку, який замінює fillInStackTrace()
метод. Недоліком є те, що printStackTrace()
методи винятку не дадуть вам корисної інформації ... якщо вам коли-небудь доведеться їх викликати.
2 - Синдром коду спагетті породив підхід структурованого програмування , де ви обмежили використання доступних конструкцій мови. Це може бути застосовано до BASIC , Fortran та COBOL , але це вимагало уваги та дисципліни. Позбутися goto
цілком було прагматично кращим рішенням. Якщо ви тримаєте його на мові, завжди є якийсь клоун, який цим зловживає.
Для розваги, ось реалізація GOTO в Java.
Приклад:
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 }
Запуск:
$ java -cp bin:asm-3.1.jar GotoClassLoader GotoDemo 3 2 1 0 Hello World!
Чи потрібно додавати «не використовувати!»?
Math.random()
може повернути 0. Має бути> =
Хоча деякі коментатори та прихильники аргументують, що це не goto , згенерований байт-код із наведених нижче інструкцій Java дійсно свідчить про те, що ці твердження дійсно виражають семантику goto .
Зокрема, do {...} while(true);
цикл у другому прикладі оптимізований компіляторами Java, щоб не оцінювати стан циклу.
label: {
// do stuff
if (check) break label;
// do more stuff
}
У байт-коді:
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);
У байт-коді:
2 iload_1 [check]
3 ifeq 9
6 goto 2 // Jumping backward
9 ..
continue label
це стрибок назад
// do stuff
і // do more stuff
є заявами про інтерес, continue label
"це має наслідком" стрибок назад (завдяки while(true)
заяві, звичайно). Я не знав, що це було настільки точне питання, проте ...
while(true)
Перекладається компілятором в goto
операції байт - коду. Як true
і постійний літерал, компілятор може зробити цю оптимізацію і не повинен нічого оцінювати. Отже, мій приклад насправді - goto, стрибок назад ...
Якщо ви дійсно хочете щось на зразок операторів goto, ви завжди можете спробувати перейти до іменованих блоків.
Ви повинні бути в межах блоку, щоб перейти до мітки:
namedBlock: {
if (j==2) {
// this will take you to the label above
break namedBlock;
}
}
Я не буду читати вам лекції про те, чому вам слід уникати goto's - я припускаю, ви вже знаєте відповідь на це.
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 пише:
Є дві конструкції, які дозволяють робити деякі речі, які можна робити за допомогою класичного goto.
Ще один...
Метт Вулф пише:
Люди завжди говорять про те, щоб ніколи не використовувати goto, але я думаю, що є справді хороший варіант використання реального світу, який досить добре відомий і використовується .. Тобто, обов’язково виконуючи якийсь код перед поверненням із функції .. Зазвичай його випуск замки чи ні, але в моєму випадку я хотів би мати можливість перейти до перерви безпосередньо перед поверненням, щоб я міг зробити необхідне обов'язкове очищення.
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
Блок нарешті завжди виконується, коли виходить блок спроби. Це гарантує, що блок нарешті виконується, навіть якщо трапляється несподіване виняток. Але нарешті корисний не лише для обробки винятків - це дозволяє програмісту уникнути випадкового обходу коду очищення шляхом повернення, продовження чи злому. Внесення коду очищення в блок нарешті - це завжди хороша практика, навіть коли не передбачаються винятки.
Дурне запитання інтерв’ю, пов’язане з нарешті, полягає в наступному: Якщо ви повертаєтесь із блоку try {}, але також маєте повернення у своєму нарешті {}, яке значення повертається?
return
в finally
блоці є поганою ідеєю. (І навіть якщо знання не є суворо необхідними, мене хвилював би програміст, у якого не було цікавості це дізнатись ...)
Найпростіший:
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;
}
}
Спробуйте код нижче. Це працює для мене.
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 не має goto
, оскільки робить код неструктурованим і незрозумілим для читання. Однак ви можете використовувати break
і continue
як цивілізовану форму goto без проблем.
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");
Вихід :
Before Break
After ahead
before: {
System.out.println("Continue");
continue before;
}
Це призведе до нескінченного циклу, оскільки кожного разу, коли рядок continue before
виконується, потік коду починатиметься зновуbefore
.
goto
він доступний на Java? Я думаю, що в цьому полягає важливіше питання.