【问题标题】:Lazy initialization of static variables in Java - execute around?Java中静态变量的延迟初始化 - 执行?
【发布时间】:2013-12-02 19:12:41
【问题描述】:

我就是这样做的(安卓代码)

private volatile static WifiManager wm;

private static WifiManager wm(Context ctx) {
    WifiManager result = wm;
    if (result == null) {
        synchronized (WifiMonitor.class) { // the enclosing class
            result = wm;
            if (result == null) {
                result = wm = (WifiManager) ctx
                    .getSystemService(Context.WIFI_SERVICE);
                if (result == null) throw new WmNotAvailableException();
            }
        }
    }
    return result;
}

Bloch in Effective Java 推荐:

// Lazy initialization holder class idiom for static fields
private static class FieldHolder {

    static final FieldType field = computeFieldValue();
}

static FieldType getField() {
    return FieldHolder.field;
}

这具有省去同步的优点,并且 JVM 优化了字段访问。问题是我需要一个 Context 对象。所以:

  • 有没有办法让 Bloch 的模式适应我的情况(computeFieldValue() 需要一个参数)?
  • 如果没有,有没有办法execute around ?代码很微妙,我宁愿把它放在一个地方,只传递所需的行为
  • 最后但并非最不重要 - 有没有办法仅通过 wm() 方法强制访问缓存字段 (wm) ?所以我可以避免 NPE 等。其他语言为此使用属性

【问题讨论】:

  • 该方案依赖于在调用 getField 之前未初始化的 FieldHolder 类。但是,JVM 规范对于何时可以进行类初始化有很大的余地,因此可以更早地进行。
  • 坦率地说,使用synchronized 的技术是“显而易见的”,易于理解,并且不依赖于任何晦涩或未记录的行为。我看不出有什么问题。如果您愿意,您可以随时将“内部”放在同步的静态方法中,以将其划分得更多。
  • @HotLicks:这是问题 2 :)

标签: java static initialization lazy-loading field


【解决方案1】:

您可以执行以下操作

static int param1;
static String param2;

public static void params(int param1, String param2) {
     this.param1 = param1;
     this.param2 = param2;
}

private static class FieldHolder {

    static final FieldType field = new FieldType(param1, param2);
}

static FieldType getField() {
    return FieldHolder.field;
}

注意:比这更简单的是使用枚举,

enum Singleton {
    INSTANCE;
}

class SingletonParams {
    static X param1;
}

enum Singleton implements MyInterface {
     INSTANCE(SingletonParams.param1, ...);
}

【讨论】:

  • 让我消化一下,然后我会回复 - 我喜欢枚举 btw :)
猜你喜欢
  • 2011-11-17
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多