Java:如何从被调用的方法中“打破”循环?

5
我有一个小程序的问题。我使用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
  }

1
如果返回了某个错误代码,就只需返回该代码并中断循环。 - janoliver
你想要中断哪个循环?theMethod里面还有另一个循环吗? - fmucar
如果不修改 while 循环中的代码,那是不可能的。哪一部分属于哪个类,以及哪些类不能进行更改? - Daniel Fischer
4个回答

7

这里有几件事情可以做。最终你所做的应该取决于你的编码风格以及你想要实现什么目标。

选项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已经想要返回其他类型。我来自C语言的背景,所以我最常用的习惯用法是“输出参数”。这让我想到了选项3:
选项3 - 输出参数让调用者决定何时终止:
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中工作以来已经过了一段时间,所以我可能写的不是最通顺的代码。 :-)


我认为他不能修改循环的内容,只能修改方法。但无论如何都是很好的答案。+1 - eboix
谢谢!当我看到“throw new”时,我明白了我应该如何做。 - christophercarlsson
等等,所以你一直可以抛出异常?在循环的其余部分中有一些捕获语句吗? - eboix
1
我好像错过了你不能修改代码的那一部分。如果有老师告诉你这个,我认为他们的教育方法非常愚蠢。这就像说:把这个钉牢,但不要使用锤子。 - asveikau

3

添加一个返回值,表示 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");
   }
}

我无法更改包含循环的类的代码,也无法更改方法的类型 :( - christophercarlsson
@user1092483:那你能改变什么呢? - Tudor

1
等等,我理解对了吗?你有一个循环询问一个数字,如果该数字不是-10,就执行某些操作,否则就退出循环?
如果是这样,请看这个:
while(true) {
    number=Integer.parseInt( JOptionPane.showInputDialog( "bla bla" ) );
    if(number == -10) {
        break;
    }
    themethod(number);
}

否则,如果不是这种情况,并且您想要分为两种情况,即-10情况和方法为false的情况,您可以这样做:
将您的方法更改为返回布尔值。如果它为true,则不想中断。如果它为false,则希望中断,然后执行以下操作:
while(true) {
    number=Integer.parseInt( JOptionPane.showInputDialog( "bla bla" ) );
    if(number == -10) {
        break;
    }
    if(!themethod(number)) break;
}

如果你真的不能编辑循环,那么就从方法中抛出一个异常!这将退出整个程序。然而,我没有看到其他可能的方法。


等一下,为什么不能编辑这个类?你能编辑循环的条件吗? - eboix
嗯...那就触发一个异常吧。你在课堂上一直在做什么?也许知道这个会给我们一个提示,告诉你们期望你们做什么。 - eboix
我们已经谈论过异常,但当我尝试添加它时,它仍然不起作用。问题在于,当我输入负数时,此方法后面的方法仍然被执行,如果我输入负数,则它们会失败。 - christophercarlsson
也许你可以发布你的全部代码。我有一种感觉,我们看不到更多的东西。 "bla" 可能是答案的关键。 - eboix

0

如果themethod(int)没有返回值,并且不更改其他类的代码,这是不可能的,因为现在没有返回通信。你必须同时更改它们两个;否则就无法在循环中更改逻辑。


2
那么就没有办法从while循环中进行控制性的跳出;你只能使用System.exit(0);来终止整个程序,或者抛出异常并希望循环能够处理它。也许您可以发布完整的代码?此外,请在您的问题中添加一个“作业”标签。 - G. Bach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接