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

我之前写过如下内容:

我得到错误“不能引用在不同方法中定义的内部类中的非最终变量”。 这发生在名为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);
}

当前回答

因为如果变量不是final,就会令人困惑,因为匿名类中不会提取对它的更改。

只需要让变量“price”和“lastPrice”成为final。

——编辑

很明显,在你的函数中,你也不需要给它们赋值。您需要新的局部变量。不管怎样,我怀疑现在已经有人给了你一个更好的答案。

其他回答

对我来说有用的是定义函数外面的变量。

就在主函数declare之前,即。

Double price;
public static void main(String []args(){
--------
--------
}

使用匿名类时,只能从包含类中访问最终变量。因此,您需要声明正在使用的变量为final(这对您来说不是一个选项,因为您正在更改lastPrice和price),或者不要使用匿名类。

因此,您的选择是创建一个实际的内部类,您可以在其中传递变量并以正常方式使用它们

or:

对于你的lastPrice和price变量,有一个快速(在我看来很难看)的方法,就是像这样声明它

final double lastPrice[1];
final double price[1];

在匿名类中,你可以这样设置值

price[0] = priceObject.getNextPrice(lastPrice[0]);
System.out.println();
lastPrice[0] = price[0];

我只是写了一些东西来处理作者的意图。 我发现最好的办法是让构造函数取所有的对象,然后在你实现的方法中使用构造函数对象。

但是,如果您正在编写一个泛型接口类,那么您必须传递一个Object,或者最好是一个Object列表。这可以通过Object[]完成,甚至更好,Object…因为这样更容易打电话。

请看下面的例子。

List<String> lst = new ArrayList<String>();
lst.add("1");
lst.add("2");        

SomeAbstractClass p = new SomeAbstractClass (lst, "another parameter", 20, true) {            

    public void perform( ) {                           
        ArrayList<String> lst = (ArrayList<String>)getArgs()[0];                        
    }

};

public abstract class SomeAbstractClass{    
    private Object[] args;

    public SomeAbstractClass(Object ... args) {
        this.args = args;           
    }      

    public abstract void perform();        

    public Object[] getArgs() {
        return args;
    }

}

请参阅这篇关于Java闭包的文章,它支持开箱即用: http://mseifed.blogspot.se/2012/09/closure-implementation-for-java-5-6-and.html

版本1支持通过自动转换传递非最终闭包: https://github.com/MSeifeddo/Closure-implementation-for-Java-5-6-and-7/blob/master/org/mo/closure/v1/Closure.java

    SortedSet<String> sortedNames = new TreeSet<String>();
    // NOTE! Instead of enforcing final, we pass it through the constructor
    eachLine(randomFile0, new V1<String>(sortedNames) {
        public void call(String line) {
            SortedSet<String> sortedNames = castFirst();  // Read contructor arg zero, and auto cast it
            sortedNames.add(extractName(line));
        }
    });

如果您想在匿名类中的方法调用中更改一个值,该“值”实际上是一个Future。所以,如果你用番石榴,你可以写

...
final SettableFuture<Integer> myvalue = SettableFuture<Integer>.create();
...
someclass.run(new Runnable(){

    public void run(){
        ...
        myvalue.set(value);
        ...
    }
 }

 return myvalue.get();

你可以在外部类之外声明变量。在此之后,您将能够从内部类中编辑变量。我有时会遇到类似的问题,而在android编码,所以我声明变量为全局,它为我工作。