Java: цикл "Break" из вызываемого метода? - PullRequest
5 голосов
/ 11 декабря 2011

У меня есть небольшая проблема с моей маленькой программой.У меня есть JOptionPane, запрашивающий число, и, если это число меньше 10, цикл, который просто продолжается и вечно делает то, что в нем, продолжает спрашивать цифры.Внутри этого цикла я вызываю метод с параметром int.В этом методе мне нужно (без изменения какого-либо кода в классе, который вызывает метод) выяснить, меньше ли введенное число меньше 1. Если это так, мне нужно вызвать другой метод.Это немного сделано.

Но!Основной цикл продолжает вращаться, поэтому он продолжает делать другие вещи в цикле.Мне нужно помешать ему сделать это, поэтому в операторе if в методе мне нужно разорвать ту конкретную итерацию цикла, в которой находится метод, и заставить его перейти к новой итерации того же цикла, запрашиваяновый номер.

Первый класс (пример):

number=Integer.parseInt( JOptionPane.showInputDialog( "bla bla" ) );
while (number !=- 10) {
  themethod(number);
  blah
  blah
  ...
}

Вызванный метод (пример):

public void themethod(int number) {
  if (number<1) {
    call the other method
    break the iteration im in
  }

Ответы [ 4 ]

7 голосов
/ 11 декабря 2011

Есть несколько вещей, которые вы можете сделать здесь. В конечном счете, то, что вы делаете, должно зависеть от вашего стиля кодирования и того, что вы пытаетесь достичь.

Вариант 1 будет иметь некоторые вариации:

for (;;)
{
   int number = /* ... */;
   myMethod(number);
   if (number == -10)
      break;
}

Вы можете сказать, довольно субъективно и в зависимости от обстоятельств, что это плохо, потому что знание условия завершения содержится в цикле, а не в методе, выполняющем «реальную работу». Может быть, для вашего цикла это нормально. Может быть, в других обстоятельствах (или, возможно, с другими программистами? Это очень зависит от вкуса.) Вы можете принять myMethod, чтобы принять это решение. В общем, мой личный вкус обычно сводится к тому, что знание сценариев не должно распределяться по различным источникам, а в одном месте.

Таким образом, большая часть того, что я напишу здесь, будет о том, как заставить myMethod принять решение о том, прекратить или нет.

Вариант 2 - myMethod возвращает логическое значение, указывающее, что мы должны завершить:

for (;;)
{
   int number = /* ... */;
   if (myMethod(number))
      break;
}

boolean myMethod(int number)
{
   // TODO - do stuff

   return number == -10;
}

Но вы можете сказать, что myMethod уже хочет вернуть какой-то другой тип. Я родом из языка Си, поэтому идиома, к которой я больше всего привык, - это «параметр out». Приводит меня к варианту 3:

Опция 3 - параметр Out позволяет вызывающему абоненту решить прекратить:

public class CancelIndicator
{
   public boolean shouldCancel;
};

CancelIndicator cancel = new CancelIndicator();

while (!cancel.shouldCancel)
{
   int number = /* ... */;
   myMethod(number, cancel);
}

int myMethod(int number, CancelIndicator cancel)
{
   // TODO - do stuff.

   cancel.shouldCancel = (number == -10);

   return /* ... */;
}

Или, может быть, вы больше поклонник исключений:

Вариант 3:

public class CancellationException extends Exception
{
}

try
{
   for (;;)
   {
      int number = /* ... */;
      myMethod(numberl);
   }
}
catch (CancellationException ex)
{
}

void myMethod(int number) throws CancellationException
{
   // TODO - do stuff.

   if (number == -10)
      throw new CancellationException();
}

Как видите, есть несколько вариантов. Я уверен, что можно провести целый день, обсуждая разные способы сделать это. Вот мой пример идиом, которые я видел - я предупреждаю вас, что прошло много времени с тех пор, как я много сделал на Java, поэтому я мог бы не написать здесь самый идиоматический код. : -)

2 голосов
/ 11 декабря 2011

Добавить возвращаемое значение, указывающее, что while должно прерваться:

public boolean themethod(int number) {
   if(number<1) {
     call the other method
     return true;
   }
   return false;
}

Тогда:

while(number !=-10) {
  if(themethod(number)) break;
  bla
  bla
  ...
}

Редактировать : Если вы не можете изменить времякод, выбросить исключение из метода:

public void themethod(int number) {
   if(number<1) {
     call the other method
     throw new RuntimeException("Negative Number");
   }
}
1 голос
/ 11 декабря 2011

Подождите, так я понял это прямо? У вас есть цикл, который запрашивает число, что-то делает, если число не равно -10, а в противном случае прерывается?

Если это так, посмотрите на это:

while(true) {
    number=Integer.parseInt( JOptionPane.showInputDialog( "bla bla" ) );
    if(number == -10) {
        break;
    }
    themethod(number);
}

В противном случае, если это не так, и вы хотите разбить в двух случаях, -10 случай и метод ложный случай, вы можете сделать это:

Измените свой метод, чтобы он возвращал логическое значение. Если это правда, то это не хочет сломаться. Если это ложь, то она хочет сломаться, тогда сделайте это:

while(true) {
    number=Integer.parseInt( JOptionPane.showInputDialog( "bla bla" ) );
    if(number == -10) {
        break;
    }
    if(!themethod(number)) break;
}

Если вы действительно не можете редактировать цикл, просто выбросьте исключение из метода! Это выйдет из всей вашей программы, хотя. Однако я не вижу другого возможного способа сделать это.

0 голосов
/ 11 декабря 2011

Без возвращаемого значения для themethod(int) и без изменения кода другого класса это невозможно, так как обратная связь отсутствует. Вам придется изменить оба; это не может быть сделано без изменения логики в цикле.

...