不能在不同方法中定义的内部类中引用非最终变量 [英] Cannot refer to a non-final variable inside an inner class defined in a different method

查看:31
本文介绍了不能在不同方法中定义的内部类中引用非最终变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要更改几个变量的值,因为它们通过计时器运行多次.我需要通过计时器在每次迭代中不断更新值.我无法将值设置为最终值,因为这会阻止我更新值,但是我收到了我在下面的初始问题中描述的错误:

Edited: I need to change the values of several variables as they run several times thorugh a timer. I need to keep updating the values with every iteration through the timer. I cannot set the values to final as that will prevent me from updating the values however I am getting the error I describe in the initial question below:

我之前写过以下内容:

我收到错误无法引用以不同方法定义的内部类中的非最终变量".

I am getting the error "cannot refer to a non-final variable inside an inner class defined in a different method".

这种情况发生在称为 price 的 double 和称为 priceObject 的 Price 上.你知道为什么我会遇到这个问题.我不明白为什么我需要一个最终声明.此外,如果您能看到我正在尝试做什么,我该怎么做才能解决这个问题.

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 不支持真正的 closures,即使使用像您在这里使用的匿名类 (new TimerTask() { ... }) 看起来像一种闭包.

Java doesn't support true closures, even though using an anonymous class like you are using here (new TimerTask() { ... }) looks like a kind of closure.

编辑 - 请参阅下面的评论 - 正如 KeeperOfTheSoul 指出的那样,以下不是正确的解释.

这就是它不起作用的原因:

This is why it doesn't work:

变量 lastPrice 和 price 是 main() 方法中的局部变量.您使用匿名类创建的对象可能会持续到 main() 方法返回之后.

The variables lastPrice and price are local variables in the main() method. The object that you create with the anonymous class might last until after the main() method returns.

main()方法返回时,局部变量(如lastPriceprice)会从栈中清除,所以main() 返回后,它们将不再存在.

When the main() method returns, local variables (such as lastPrice and price) will be cleaned up from the stack, so they won't exist anymore after main() returns.

但是匿名类对象引用了这些变量.如果匿名类对象在变量被清理后试图访问它们,事情就会变得非常糟糕.

But the anonymous class object references these variables. Things would go horribly wrong if the anonymous class object tries to access the variables after they have been cleaned up.

通过使 lastPriceprice final,它们不再是真正的变量,而是常量.然后编译器可以用常量的值(当然是在编译时)替换匿名类中 lastPriceprice 的使用,而你不会再有访问不存在的变量的问题.

By making lastPrice and price final, they are not really variables anymore, but constants. The compiler can then just replace the use of lastPrice and price in the anonymous class with the values of the constants (at compile time, of course), and you won't have the problem with accessing non-existent variables anymore.

其他支持闭包的编程语言通过特殊处理这些变量来做到这一点 - 通过确保它们在方法结束时不会被销毁,以便闭包仍然可以访问这些变量.

Other programming languages that do support closures do it by treating those variables specially - by making sure they don't get destroyed when the method ends, so that the closure can still access the variables.

@Ankur:你可以这样做:

@Ankur: You could do this:

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);      
}

这篇关于不能在不同方法中定义的内部类中引用非最终变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆