1

这两个班级是一样的吗?

public class SingleTone {

    // yes this is a bug what if i change the class this way
    //  private static SingleTone instance = new SingleTone();
    // and empty constructor?
    private static SingleTone instance; 
    private SingleTone() {
        instance = new SingleTone();
    }

    public static SingleTone getInstance(){
        return instance;
    }
} 

public class SingleTone {

    private final static SingleTone instance = new SingleTone();

    private SingleTone() {
    }

    public static SingleTone getInstance(){
        return instance;
    }
} 

在构造函数实例化的非最终变量中是否存在任何线程安全问题?

问题2:

有什么区别

    private final static SingleTone instance = new SingleTone();

    private SingleTone() {
    }

还有这个:

    private final static SingleTone instance;

    private SingleTone() {
        instance = new SingleTone();
    }
4

3 回答 3

2

问题 1

你的第一个例子不起作用。

就像您SingleTone.getInstance()在创建该类型的对象之前进行此调用一样,它将返回 null

第二个例子工作正常

问题2

同样的情况,您在构造函数中设置了一个静态字段。这没有意义,因为您不能保证在访问静态字段之前已经调用了构造函数。

你可以这样做:

private final static SingleTone instance;

static {
    instance = new SingleTone();
}

这将在第一次加载类时实例化静态字段。


回答你的评论。

如果你这样做:

private static final SingleTone instance = new SingleTone();

这是线程安全的,就好像第一个线程还没有完成初始化类并且另一个线程尝试访问它,另一个线程将阻塞。

有关更多信息,请参阅此问题:Java 中静态块的线程安全

于 2013-03-18T12:11:34.370 回答
0

这两个选项实际上是相同的(但super()在这两种情况下都缺少构造函数中的调用)。

然而,使用私有静态字段实现单例是 Java 往往被弃用。现在,我会使用枚举。

public enum Elvis {
    INSTANCE;
    private final String[] favoriteSongs =
        { "Hound Dog", "Heartbreak Hotel" };

    public void printFavorites() {
        System.out.println(Arrays.toString(favoriteSongs));
    }
}

如果您想进一步阅读:http ://www.drdobbs.com/jvm/creating-and-destroying-java-objects-par/208403883?pgno=3

于 2013-03-18T12:15:13.420 回答
0

SingleTone 类必须返回一个引用,所以第一个例子是完全错误的。

考虑以下过程: 1. 类加载由 JVM 启动 2. 类加载到 JVM。3. 构造函数执行 4. 对象创建完成

public class SingleTone { 对于此示例,实例将在 1 和 2 之间处于活动状态 private final static SingleTone instance = new SingleTone();

private SingleTone() {
}

public static SingleTone getInstance(){
    return instance;
}

}

public class SingleTone { 对于这个例子,实例将在 3 到 4 个 private final static SingleTone 实例之间存活;

private SingleTone() {
    instance = new SingleTone();
}

public static SingleTone getInstance(){
    return instance;
}

}

于 2013-03-18T12:30:24.253 回答