当前位置: 首页 > 面试题库 >

Java-无法在用其他方法定义的内部类中引用非最终变量

融渊
2023-03-14
问题内容

编辑:我需要更改几个变量的值,因为它们在计时器中运行了几次。我需要在每次迭代中通过计时器不断更新值。我无法将值设置为final,因为这将阻止我更新值,但是我遇到了在下面的第一个问题中描述的错误:

我以前写过下面的内容:

我收到错误消息“无法引用用其他方法定义的内部类内部的非最终变量”。

对于名为double的价格和名为priceObjectPrice,这种情况正在发生。你知道我为什么会遇到这个问题吗?我不明白为什么我需要作最后声明。另外,如果你可以看到我正在尝试做什么,那么该怎么办才能解决此问题。

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() { ... })看起来就像一种闭包。

编辑 - 请参阅下面的注释-正如KeeperOfTheSoul所指出的,以下内容不是正确的解释。

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

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

main()方法返回时,局部变量(如lastPriceprice)从栈中清除,因此他们将不再存在后main()回报。

但是匿名类对象引用了这些变量。如果匿名类对象在清除变量后尝试访问变量,则事情将变得非常糟糕。

通过制作lastPriceprice final,它们不再是真正的变量,而是常量。然后,编译器就可以使用常量的值(当然是在编译时)来替换匿名类中lastPriceand 的使用price(当然是在编译时),并且访问不再存在的变量将不再有问题。

其他支持闭包的编程语言通过特殊对待那些变量来做到这一点-确保方法结束时它们不会被破坏,以便闭包仍然可以访问变量。

你可以这样做:

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


 类似资料:
  • 问题内容: 我需要更改几个变量的值,因为它们在计时器中运行了几次。我需要通过计时器在每次迭代中不断更新值。我无法将值设置为final,因为这将阻止我更新值,但是我遇到了在下面的的错误: 无法引用用其他方法定义的内部类内部的非最终变量 问题答案: Java不支持真正的闭包,即使使用像你在此使用的匿名类()看起来就像一种闭包。 这就是为什么它不起作用的原因: 变量和价格是方法中的局部变量。你使用匿名类

  • 问题内容: 我有按钮单击侦听器,并且在方法中我有一个局部变量,例如 为什么Java要求让我最终决定? 问题答案: 当onCreate()方法返回时,您的局部变量将从堆栈中清除,因此它们将不再存在。但是匿名类对象new View.OnClickListener()引用了这些变量。当然,这是错误的行为,因此Java不允许您执行此操作。 最终确定后,它将成为一个常数。因此它存储在堆中,可以在匿名类中安全

  • 在此代码示例中,ActionListener的actionPerformed函数中没有使用最终对象jLabel:

  • 我将简单类添加到我的应用程序中: 应用程序应该使用这个类中的一个对象。当我在活动中使用它时: I get error:无法在不同方法Presmena中定义的内部类中引用非最终变量Asortion。JAVA帮助理解,什么是错的

  • 在中定义额外的方法(不重写超类方法)时,代码编译良好,没有任何问题,但如果我试图调用额外的方法,它会抛出错误。那么,在使用扩展时,是否只有在子类中的方法才可能?如果是这样,谁能解释一下为什么? 下面是我的代码的样子 这就是我得到的错误

  • 问题内容: 我对内部类和lambda表达式有些困惑,我试图问一个问题,但随后又产生了一个疑问,发布另一个问题可能比评论前一个问题更好。 直截了当:我知道这样的东西不会编译 由于Java如何管理闭包,因为它不是 [有效地]最终的 ,依此类推。 但是,这怎么允许呢? 不等于?在第二种情况下,我是否不会面临“使用过时的变量”的风险? 我的意思是,在后一种情况下,执行后仍然具有过期的副本(即引用旧对象)。