虽然循环没有目的?

时间:2014-05-27 20:56:33

标签: java while-loop

在阅读Java教程书时,我遇到了这段代码:

while(getImage().getWidth(frame) <= 0);

我起初认为这是一个错字,但在整本书中,它在多个地方重复了几次。很遗憾没有解释它的作用,所以我想知道它的目的是什么。从表面上看,我知道它基本上什么都不做,因为即使它可以返回truefalse,但是没有body语句。这是一个特殊的语法案例吗?事实上,它做了什么?或者这只是毫无意义的代码,它不会对代码流产生负面影响(它不会返回任何错误,并且所有内容都按预期运行)。

以下是完整的方法,如果它有帮助:

public void load(String filename)
{
    Toolkit tk = Toolkit.getDefaultToolkit();
    image = tk.getImage(getURL(filename));
    while(getImage().getWidth(frame) <= 0);
    double x = frame.getSize().width / 2 - width() / 2;
    double y = frame.getSize().height / 2 - height() / 2;
    at = AffineTransform.getTranslateInstance(x, y);
}

3 个答案:

答案 0 :(得分:6)

从AWT Toolkit获取的图像异步加载,这意味着您在图像加载完成之前获取了Image实例。 只要图像未完全加载,其尺寸可能尚未知晓,当您检查图像的宽度和高度时,它将返回负值(-1,-1)。 循环实现轮询图像尺寸(或此处:宽度),直到加载图像。

当然,这是不是推荐的方法(因为它让线程忙于什么)。相反,可以使用MediaTracker类等待图像完全加载:

MediaTracker tracker = new MediaTracker(new Canvas());
tracker.addImage(image, 0);
try {
    tracker.waitForAll();
}
catch (InterruptedException ex) {}

答案 1 :(得分:2)

正在执行一项名为忙碌等待的事情。它通常是不受欢迎的,只有在没有其他办法确定何时完成另一项任务时才应该使用它。

答案 2 :(得分:2)

while循环将在每次程序循环循环时重新评估表达式。如果同一个表达式涉及一个方法调用,它可以根据其他东西的状态改变值,那么while循环可能有意义;语法没有什么特别之处。

我们显然正在处理一个函数,该函数将返回0或负数,直到发生其他事情。例如,在Android中,有一个getWidth()将返回0,直到在屏幕上呈现布局,由其他一些线程呈现,并且在发生这种情况之前不会计算宽度。但是使用繁忙的循环来等待事情的发生绝对是Android上的错误方法,并且在其他情况下也可能是错误的。并且使用一个不会在检查之间暂停呼叫的繁忙循环非常糟糕,可能会冻结应用程序。

但另一点是,尽管这样的循环是合法的,有时也很有用,但这是一种写它的糟糕方式。更好的是

while (getImage().getWidth(frame) <= 0)
    ;

while (getImage().getWidth(frame) <= 0)
    /* nothing */ ;

while (getImage().getWidth(frame) <= 0) {
}

所有这些都让读者清楚地知道这不是一个错字(尽管最后一个看起来好像他们计划稍后添加一个身体而忘记了)。

但是,超越可读性问题,你真正想要的可能更像是

  while (getImage().getWidth(frame) <= 0) {
      try {
          Thread.sleep(100);
      } catch (InterruptedException e) {
          break;
      }

或如果可能,请使用waitnotify,或其他各种同步方法。