避免在 java 中实例化类

2022-09-02 00:35:17

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

但是,我的回答是:

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

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

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


答案 1

我想到了四个原因:

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

作为 (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
  }
}

注意:不需要无参数构造函数,因为另一个构造函数是显式定义的。


答案 2

不是真正回答你的问题,而只是一个注意:

当您创建一个私有的no-arg构造函数来防止实用程序类的实例化时,您应该让构造函数抛出一个异常(例如,不支持的OperationException)。这是因为您实际上可以通过反射访问私有成员(包括构造函数)。请注意,如果这样做,则应在它后面加上注释,因为定义构造函数以防止实例化类有点违反直觉。

使实用工具类抽象不是一个好主意,因为它使类看起来像是要扩展的,而且您可以扩展类,从而对其进行实例化。