在阅读Java教程书时,我遇到了这段代码:
while(getImage().getWidth(frame) <= 0);
我起初认为这是一个错字,但在整本书中,它在多个地方重复了几次。很遗憾没有解释它的作用,所以我想知道它的目的是什么。从表面上看,我知道它基本上什么都不做,因为即使它可以返回true
或false
,但是没有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);
}
答案 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;
}
或如果可能,请使用wait
和notify
,或其他各种同步方法。