我正在使用Java for Android构建单例服务:
final class MyService {
private static Context context = null;
// ...
private MyService() {
myObj = new MyObj(context);
// ...
}
private static class Singleton {
private static final MyService INSTANCE = new MyService();
}
/**
* a singleton - do not use new(), use getInstance().
*/
static synchronized myService getInstance(Context c) {
if (context == null) context = c;
return Singleton.INSTANCE;
}
为了提高性能,我始终使用静态变量和方法。
我的问题:
对象,new()确保 初始化该对象的机会 在使用之前。有没有 相当于一个静态类?对于 示例:静态方法依赖时 在早期初始化 - 如此 就像上面的“背景”一样 - 是有的 一种确保的方法 初始化首先发生?我必须吗 如果没有,会抛出异常吗?
因为这是静态的我期待的 只有班级本身:是 根据定义,单身?是 上面推荐的代码就是 防止实例化的方法 对象
提前致谢!
答案 0 :(得分:2)
这当然是创建单身人士的一种方式。我想你可以取消静态助手;因性能原因而静态实际上并没有节省太多,而且会使代码混淆。
我认为你真正的问题是,在context
不为空之前,是否可以延迟构造静态。答案取决于VM;在大多数“vanilla”Java VM中,INSTANCE
实际上不会在第一次调用GetInstance()
之前进行实例化。静态评估静态以获得更好的启动性能。这意味着只要context
在第一次调用GetInstance()
之前获得了其他内容,就会很好。
但是,请原谅我,但我不知道Android VM中的这种行为是否有所不同,Android VM在技术上不是“真正的”Java VM(Sun / Oracle也是如此)。为了安全起见,如果context
在静态构造函数被调用时没有实例,我会在实例化之前使用静态工厂方法或简单的IoC来解析静态构造函数中的一个实例。 INSTANCE
。
答案 1 :(得分:1)
您可以向班级添加静态初始化块
public class MySingleton {
/* Default constructor */
private MySingleton() {
}
static {
//Static init stuff...
}
...
}
}
静态初始化程序块将为每个加载类的类加载器调用一次 - 通常在进程的生命周期内只调用一次。
最后,根据定义,您的单例只会被创建一次,因此使用静态助手来完成工作不会带来性能上的好处。
答案 2 :(得分:0)
代码中存在缺陷。如果您使用其他 getInstance()
第二次致电Context
,该怎么办?您将获得一个使用错误上下文创建的实例,即第一次传入的实例。我不确定这是否是故意的,但这至少没有任何意义,它可能导致混乱和讨厌的错误。
如果目的是为每个特定的上下文返回相同的实例,我会使用以下内容:
public class Service {
private static final Map<Context, Service> services = new HashMap<Context, Service>();
private Context context;
private Service(Context context) {
this.context = context;
}
public static synchronized Service getInstance(Context context) {
Service service = services.get(context);
if (service == null) {
service = new Service(context);
services.put(context, service);
}
return service;
}
}
这称为Multiton。它是Factory和Flyweight的组合。 synchronized
修饰符在广泛使用时非常昂贵,您可以考虑使用ReentrantReadWriteLock
。维基百科文章包含一个例子。
回到单身人士的故事,维基百科有several good examples。一个在类加载期间构造单例的基本元素,另一个在第一个请求时构造单例的元素。但一般来说,不鼓励使用这种模式。
答案 3 :(得分:0)