4

我最近爱上了使用如下的延迟加载技术:

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() 和同步来做到这一点,但是如果在静态情况下可能的优雅技术也可以在这里以某种方式使用,我将不胜感激。

4

2 回答 2

4

对于有经验的程序员来说,你所看到的“优雅”看起来令人困惑和愚蠢。

当您查看以下示例时,您会发现语言或类加载器规范不会导致隐式副作用。它所做的一切都在您看到的代码中。你也明白诡计并不美丽。

public synchronized double getNextDouble() {
    if (r == null) {
        r = new Random();
    }
    return r.nextDouble();
}

您可能还会意识到,如果您爱上了一把锤子,那么您所有的问题都开始看起来像钉子。:)

于 2012-04-24T12:40:49.037 回答
0

您描述的技术依赖于 Java 的延迟类加载(由规范保证),因此它仅适用于应用程序范围的单例。您要实现的是将实例变量传递给惰性初始化对象。如果您仍然希望它是应用程序范围的单例并且只初始化一次,您仍然可以通过将种子写入静态类将看到的静态字段来使其工作。

于 2012-04-24T12:52:48.827 回答