我最近爱上了懒惰加载技术,使用如下:
public class SomeClass
{
static class ComplexClassHolder
{
static ComplexClass complex = new ComplexClass(); // takes a long time
}
static double someMethod(int x, int y)
{
return ComplexClassHolder.complex.calculate(x,y);
}
public double quickMethod() // if only this method is called there is no initialization of the instance of ComplexClass
{
return 1.0+1.0;
}
}
但对于非静态方法,是否也有类似的技术?
示例
import java.util.Random;
public class SomeClass
{
final int seed;
public SomeClass(int seed)
{
this.seed=seed;
}
class ComplexClassHolder
{
Random r = new Random(SomeClass.this.seed); // let's pretend this takes a long time
}
public double randomDouble()
{
return ComplexClassHolder.r.nextDouble();
}
}
问题是以上是不可能的,因为ComplexClassHolder和ComplexClassHolder.r不是静态的。但是,如果我将它们设为静态,我就无法访问SomeClass.this.seed。
我知道我可以使用getInstance()和同步来实现它,但是如果真的很感激,如果静态情况下可能的优雅技术也可以在这里使用。
答案 0 :(得分:4)
你所看到的“优雅”看起来让有经验的程序员感到困惑和愚蠢。
当您查看以下示例时,您会发现语言或类加载器规范没有导致隐式副作用。它所做的一切都在你看到的代码中。你也明白这种诡计并不美丽。
public synchronized double getNextDouble() {
if (r == null) {
r = new Random();
}
return r.nextDouble();
}
你可能也会意识到,如果你爱上了锤子,你所有的问题都会开始像钉子一样。 :)
答案 1 :(得分:0)
您描述的技术依赖于Java的惰性类加载(由规范保证),因此它仅适用于应用程序范围的单例。您要实现的是将实例变量传递给惰性对象。如果你仍然希望它是一个应用程序范围的单例并且只初始化一次,你仍然可以通过将种子编写到静态类将看到的静态字段来使其工作。