【问题标题】:Dealing with Singletons which have to subclass处理必须子类化的单例
【发布时间】:2012-07-12 13:33:01
【问题描述】:

在问题What is an efficient way to implement a singleton pattern in Java? 中,获得最多支持的答案是使用枚举来实现单例。

很好,我理解这些论点,分别是语言优势。

然而,我有一组类,我定义了单例但需要扩展其他类,这对于枚举方法是不可能的,因为枚举不能子类化

Joshua Bloch 在他的幻灯片中说:

  • 但是缺少一件事——不能扩展枚举类型
    • 在大多数情况下,您不应该
    • 一个引人注目的用例 - 操作代码

在大多数情况下,您不应该:有人能详细说明一下吗?我已经实现了几个 servlet,它们扩展了HttpServlet,为什么这些不应该是单例?我的应用程序中只需要它们的一个实例。

【问题讨论】:

  • 请你解释一下为什么你想要一个单例 servlet(导致这个选择的限制是什么)?
  • @Romski 应用程序只需要这个 servlet 的一个实例。
  • 枚举可以实现接口。使用委托,这意味着您只有一个实例使用另一个类中定义的功能。

标签: java servlets enums singleton


【解决方案1】:

单例类可以扩展其他类;实际上默认情况下在 Java 中它无论如何都会扩展 Object.然而 Josh 所指的是你不应该扩展一个 Singleton 类,因为一旦你扩展它,就会出现不止 1 个实例。

回复评论:

其实实现单例最好的方式是:

来自有效的 Java

// 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() { ... }
}

这里 Elvis 可以扩展任何其他类。

【讨论】:

  • 这如何帮助我使用枚举习语实现我的 servlet?使用枚举类型实现的 Singleton 类,不能扩展其他类。
  • 不,“Effective Java”的在线部分提到了枚举方法。 >> 这种方法在功能上等同于公共字段方法,只是它更简洁,免费提供序列化机制,并且即使面对复杂的序列化或反射攻击,也能提供针对多次实例化的铁定保证。虽然这种方法尚未被广泛采用,但单元素枚举类型是实现单例的最佳方式
  • 也许我应该说,更好的方法之一。但对你来说,这将是最好的方式,因为你想扩展。
【解决方案2】:

您不应该关心 servlet 的实际实例 - 生命周期管理由 servlet 容器根据您同意的 Servlet 规范合同处理。如果将部分服务器端功能实现为单例是有意义的,那么请继续按照您喜欢的方式执行此操作,并从您的 servlet 中使用它。

【讨论】:

  • 这个问题解决了我的问题,但由于我的问题更笼统,我决定将另一个问题作为例外检查。还是谢谢!
【解决方案3】:

Josh 指的是扩展枚举类型,而不是让单例类型扩展其他东西。

【讨论】:

  • 但是我不能用枚举单例习惯实现我的 servlet,因为这样它就不能继承 HttpServlet: public enum MyServlet extends HttpServlet 是不允许的。我不想扩展我的单例,我想让我的单例扩展另一个类。
  • 是的,很清楚。我的意思是 Josh 并没有在这句话中解决这个问题 ;) 很明显,在这种情况下你不能使用 enum 成语,那么问题是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
相关资源
最近更新 更多