编辑:我需要更改几个变量的值,因为它们在计时器中运行了几次。我需要在每次迭代中通过计时器不断更新值。我无法将值设置为final,因为这将阻止我更新值,但是我遇到了在下面的第一个问题中描述的错误:
final
我以前写过下面的内容:
我收到错误消息“无法引用用其他方法定义的内部类内部的非最终变量”。
对于名为double的价格和名为priceObject的Price,这种情况正在发生。你知道我为什么会遇到这个问题吗?我不明白为什么我需要作最后声明。另外,如果你可以看到我正在尝试做什么,那么该怎么办才能解决此问题。
double
priceObject
Price
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不支持真正的闭包,即使使用像你在此使用的匿名类(new TimerTask() { ... })看起来就像一种闭包。
Java
(new TimerTask() { ... })
编辑 - 请参阅下面的注释-正如KeeperOfTheSoul所指出的,以下内容不是正确的解释。
KeeperOfTheSoul
这就是为什么它不起作用的原因:
变量lastPrice和价格是main()方法中的局部变量。你使用匿名类创建的对象可能会持续到该main()方法返回之后。
lastPrice
main()
当main()方法返回时,局部变量(如lastPrice和price)从栈中清除,因此他们将不再存在后main()回报。
main()
price
但是匿名类对象引用了这些变量。如果匿名类对象在清除变量后尝试访问变量,则事情将变得非常糟糕。
通过制作lastPrice和price final,它们不再是真正的变量,而是常量。然后,编译器就可以使用常量的值(当然是在编译时)来替换匿名类中lastPriceand 的使用price(当然是在编译时),并且访问不再存在的变量将不再有问题。
price final
lastPriceand
其他支持闭包的编程语言通过特殊对待那些变量来做到这一点-确保方法结束时它们不会被破坏,以便闭包仍然可以访问变量。
你可以这样做:
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); }