避免在java中实例化一个类

时间:2009-08-25 05:31:56

标签: java class instantiation

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

然而,我回答说:

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

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

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

5 个答案:

答案 0 :(得分:26)

有四个原因让人想起:

  1. 允许子类但不允许实例化父类;
  2. 禁止直接实例化,而是提供工厂方法返回,并在必要时创建实例;
  3. 因为所有实例都是预定义的(例如适用于卡片组)但是从Java 5开始,建议使用类型安全的枚举;和
  4. 班级真的不是班级。它只是静态常量和/或方法的持有者。
  5. 作为(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构造函数,因为显式定义了另一个构造函数。

答案 1 :(得分:10)

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

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

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

答案 2 :(得分:3)

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

答案 3 :(得分:2)

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

答案 4 :(得分:1)

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

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

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