避免在java中实例化一个类

最近我遇到了一个问题: 如何避免实例化Java类?

但是,我回答说:

  1. 如果您不想实例化类,请使用“abstract”修饰符。 例如:javax.servlet.HttpServlet被声明为抽象(尽管它的方法都不是抽象的)以避免实例化。

  2. 声明一个无参数的私有构造函数。

现在我的问题是a)还有其他方法吗? b)为什么任何人都不想实例化一个类? – 在搜索SO之后,我从中了解到Util类可以不实例化。 我们不想在OOP中实例化一个类的任何其他地方?

有四个原因让人想起:

  1. 允许子类但不允许实例化父类;
  2. 禁止直接实例化,而是提供工厂方法返回,并在必要时创建实例;
  3. 因为所有实例都是预定义的(例如适用于一副卡片),但是从Java 5开始,建议使用类型安全的枚举; 和
  4. 这堂课真的不是class级。 它只是静态常量和/或方法的持有者。

作为(2)的示例,您可能想要创建规范对象。 例如,RGB颜色组合。 您不希望创建任何RGB组合的多个实例,因此您执行此操作:

public class MyColor { private final int red, green, blue; private MyColor(int red, int green, int blue) { this.red = red; this.green = green; this.blue = blue; } public static MyColor getInstance(int red, int green, int blue) { // if combo already exists, return it, otherwise create new instance } } 

注意:不需要no-arg构造函数,因为显式定义了另一个构造函数。

不是你的问题的答案,而只是一个注释:

当您创建一个私有的无参数构造函数来阻止实用程序类的实例化时,您应该让构造函数抛出exception(例如UnsupportedOperationException)。 这是因为您可以通过reflection实际访问私有成员(包括构造函数)。 请注意,如果您这样做,则应附带注释,因为定义构造函数以防止实例化类有点违反直觉。

使实用程序类抽象不是一个好主意,因为它使类看起来像是要扩展,而且你可以扩展类,从而实例化它。

有时您只想避免其他人实例化您的对象,以便完全控制所有现有实例。 一个例子是单身模式 。

我认为不想实例化类的最常见原因是当你处理静态类时,因此使用静态方法。 您不希望有人尝试实例化该类。 同样,当您处理Factory类时,或者在某些情况下,许多单例类将隐藏其构造函数,以便不以正常方式实例化。

使类不可实例化的另一种方法是将它声明为私有内部类,然后不提供任何方法在周围的类中实例化它。 但这是(IMO)毫无意义的。

如果一个类实例化它是没有意义的,那么你希望一个类是不可实例化的。 如果类实际上只是(静态)辅助方法的集合,或者类是“不完整”的,那么通常会这样做。 不完整性可能在语法上是显而易见的(即抽象方法),但还有其他类型的不完整性。 例如,您可以为所有方法提供默认的默认实现,并且需要重写其中的一个或多个以使该类执行有用的操作。

使类不可实例化(或至少不可直接实例化)的另一个原因是您的应用程序需要控制实例化。 例如,无法直接实例化java.util.regex.Pattern类,以便JRE可以(可以)维护预编译正则表达式的缓存。