如何初始化需要复杂计算的最终变量?

时间:2016-07-04 01:32:44

标签: java variables methods constructor final

我是Java的初学者。我想知道,在变量初始化之前变量需要复杂计算的情况下该怎么做,但一旦初始化,它将更改。我想让变量最终,但不是在构造函数中初始化它,我宁愿在一个方法中初始化它,所以这个方法可以在以后重用。有没有办法实现这个目标?

除了上面的所有要求之外,如果我只想在需要时计算这个变量的值,会发生什么(因为计算它的计算成本很高)。在这样的情况下我该怎么办?

3 个答案:

答案 0 :(得分:2)

很遗憾,您无法在任何特定时刻制作变量。如果变量为final,则可以(并且必须)在构造函数中初始化变量。< / p>

您也可以这样做(以下代码可归功于npinti):

private boolean isMutable;
private String someString;

public void setMutable(boolean value)
{
    this.isMutable = value;
}

public void setSomeString(String value)
{
    if (this.isMutable)
    {
        this.someString = value;
    }
}

答案 1 :(得分:2)

您可以从Guava尝试memoize供应商:

Supplier<T> something = Suppliers.memoize(new Supplier<T>() {
    // heavy computation
    return result.
});

something.get();
something.get(); // second call will return the memoized object.

答案 2 :(得分:2)

看起来你需要Lazy初始化。当结果被认为由于某种原因而变得昂贵时,使用性能是一种性能优化。目标是 延迟昂贵的计算,直到有必要和 存储昂贵计算的结果,使得计算不需要再次重复。

以下是一个例子:

public final class Foo {
    private Data data = null; 

    private Data expensiveComputation() {
        if(data == null) { // first call to this method
            Data data = new Data();
            // complex computation
            // store the result to data
        } else {
            return data;
        }
    }
}

正如您所看到的,data仅在需要时才会初始化。

请注意,如果您的代码在多线程环境中工作,则会出现问题。这是因为多个线程可以同时调用该方法。为防止这种情况,我们可以使用synchronized关键字:

public final class Foo {
    private volatile Data data = null; 

    private Data expensiveComputation() {
        if(data == null) { // first call to this method
            synchronized(Foo.class) {
                if(data == null) {
                    Data data = new Data();
                    // complex computation
                    // store the result to data
                }
            }
        } else {
            return data;
        }
    }
}

synchronized关键字只允许一个线程进入并初始化data