我是Java的初学者。我想知道,在变量初始化之前变量需要复杂计算的情况下该怎么做,但一旦初始化,它将不更改。我想让变量最终,但不是在构造函数中初始化它,我宁愿在一个方法中初始化它,所以这个方法可以在以后重用。有没有办法实现这个目标?
除了上面的所有要求之外,如果我只想在需要时计算这个变量的值,会发生什么(因为计算它的计算成本很高)。在这样的情况下我该怎么办?
答案 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
。