【发布时间】:2025-12-30 17:25:12
【问题描述】:
我刚刚和一个朋友进行了一次简短的交谈,他坚持认为用于 Dagger 的单例比通过老式静态私有变量方式制作一个更好。并不是说我确定他错了,我只是想弄清楚为什么更好。
这两种实现方式(DI vs 普通静态)有什么区别?
【问题讨论】:
-
我相信最不坏的方法是使用
enum。
标签: java android singleton dagger
我刚刚和一个朋友进行了一次简短的交谈,他坚持认为用于 Dagger 的单例比通过老式静态私有变量方式制作一个更好。并不是说我确定他错了,我只是想弄清楚为什么更好。
这两种实现方式(DI vs 普通静态)有什么区别?
【问题讨论】:
enum。
标签: java android singleton dagger
Java best practices book 解释了为什么您应该使用私有属性来强制执行 Singleton 属性 构造函数或枚举类型。这一章比较长,总结一下吧:
使一个类成为单例可以 难以测试其客户端,因为无法替代模拟实现 对于单例,除非它实现了用作其类型的接口。 在 1.5 版之前,有两种方法可以实现单例。两者都是 基于保持构造函数私有并将公共静态成员导出到 提供对唯一实例的访问。在一种方法中,成员是最终字段:
// Singleton with public final field
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public void leaveTheBuilding() { ... }
}
在实现单例的第二种方法中,公共成员是 静态工厂方法:
// Singleton with static factory
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public static Elvis getInstance() { return INSTANCE; }
public void leaveTheBuilding() { ... }
}
还有第三种实现单例的方法。通过简单 用一个元素创建一个枚举类型:
// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
此方法在功能上等同于公共字段方法,不同之处在于它 更简洁,免费提供序列化机制,并提供 对多次实例化的铁定保证,即使面对复杂的 序列化或反射攻击。
虽然这种方法尚未广泛应用 采用单元素枚举类型是实现单例的最佳方式。
【讨论】: