编辑:我需要更改几个变量的值,因为它们通过计时器运行了几次。我需要通过计时器在每次迭代中不断更新值。我无法将值设置为最终值,因为这将阻止我更新值,但是我收到了我在下面的初始问题中描述的错误:
我之前写过以下内容:
I am getting the error "cannot refer to a non-final variable inside an inner class defined in a different method".
This is happening for the double called price and the Price called priceObject. Do you know why I get this problem. I do not understand why I need to have a final declaration. Also if you can see what it is I am trying to do, what do I have to do to get around this problem.
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
double lastPrice = 0;
Price priceObject = new Price();
double price = 0;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
price = priceObject.getNextPrice(lastPrice);
System.out.println();
lastPrice = price;
}
}, delay, period);
}
Java 不支持 true closures ,即使使用像您在这里使用的匿名类 (new TimerTask() { ... }
) 看起来像是一种闭包。
编辑 - 请参阅下面的评论 - 正如 KeeperOfTheSoul 指出的那样,以下不是正确的解释。
这就是它不起作用的原因:
变量 lastPrice
和 price 是 main() 方法中的局部变量。您使用匿名类创建的对象可能会持续到 main()
方法返回之后。
当main()
方法返回时,局部变量(如lastPrice
和price
)会从栈中清除,所以main()
返回后它们将不再存在。
但是匿名类对象引用了这些变量。如果匿名类对象在清理完变量后尝试访问这些变量,事情就会大错特错。
通过使 lastPrice
和 price
final
,它们不再是真正的变量,而是常量。然后编译器可以将匿名类中 lastPrice
和 price
的使用替换为常量的值(当然是在编译时),你不会不再有访问不存在的变量的问题。
其他支持闭包的编程语言通过特殊处理这些变量来做到这一点 - 通过确保它们在方法结束时不会被破坏,以便闭包仍然可以访问变量。
@Ankur:你可以这样做:
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
// Variables as member variables instead of local variables in main()
private double lastPrice = 0;
private Price priceObject = new Price();
private double price = 0;
public void run() {
price = priceObject.getNextPrice(lastPrice);
System.out.println();
lastPrice = price;
}
}, delay, period);
}
我是一名优秀的程序员,十分优秀!