使用私有构造函数来防止类的实例化?

时间:2010-04-30 09:10:09

标签: java performance

现在我正在考虑将一个私有构造函数添加到只包含一些String常量的类中。

public class MyStrings {
  // I want to add this:
  private MyString() {}

  public static final String ONE = "something";
  public static final String TWO = "another";
  ...
}

如果我向此类添加私有构造函数以阻止某人实例化它,是否有性能内存开销?

您是否认为这是必要的,或者为此目的的私人构建者是浪费时间和代码混乱?

更新

我正在寻找一个带有私有构造函数和类的描述性javadoc的最终类。我不能使用ENUM(我更喜欢),因为我现在仍然坚持使用Java 1.4。这将是我的修改:

/**
 * Only for static access, do not instantiate this class.
 */
public final class MyStrings {
  private MyString() {}

  public static final String ONE = "something";
  public static final String TWO = "another";
  ...
}

9 个答案:

答案 0 :(得分:8)

使用私有构造函数来阻止类的实例化?

有几种方法可以让用户想到阻止Instantiations创建常量

  1. 正如您所提到的具有私有构造函数的类并具有所有字符串常量,是一种方法,即使有开销,也可以忽略不计
  2. 否则,您可以使用最终修饰符创建一个类并定义字符串常量
  3. 您可以将Abstract Class与String Constants一起使用
  4. 您可以在属性文件中定义字符串常量,并且可以从中进行访问,这肯定会减少内存并提高代码的灵活性。

答案 1 :(得分:6)

您可以添加私有构造函数,但还有其他两个选项。

在同样的情况下,我会使用一个枚举器。如果它对您的实施有意义,那么您可以使用它,如果它是publicprivate取决于您需要使用它的位置:

public enum MyStrings {

  ONE ("something"),

  TWO ("something else");

  private String value;

  private MyStrings(String str) {
     this.value = str;
  }

}

另一种选择是将它放在abstract类中,那些无法实例化:

public abstract MyStrings {

  public static final String STUFF = "stuff";
  public static final String OTHER = "other stuff";
}

对枚举器和抽象类的访问与您提供的实现一样工作:

MyStrings.STUFF

答案 2 :(得分:5)

如果你不愿意任何人制作一个类的对象,你可以像这样抽象它

public abstract class MyStrings {
  public static final String ONE = "something";
  public static final String TWO = "another";
}

并访问您的静态变量

String val1 = MyStrings.ONE;
String val2 = MyStrings.TWO;

我认为这将是一个更好的解决方案。

答案 3 :(得分:3)

对我来说,最好的解释是 Effective Java 一书:第4项:使用私有构造函数强制执行非实例化See more

摘要:

  • 私有构造函数到期实用程序类未设计为实例化,因此是设计决策。 (没有性能或内存开销)
  • 使类抽象不起作用,因为可以进行子类化然后实例化。
  • 使用抽象类,用户可能认为该类是为了继承。
  • 确保不实例化的唯一方法是添加private constructor,以确保不生成默认构造函数。
  • 私有构造函数阻止继承,因为无法调用超级构造函数(因此不需要将类声明为final)
  • 在私有构造函数中抛出错误,避免在类中调用它。

定义上,最好的方式就是下一个:

public class MyStrings {

     private MyStrings () {
       throw new AssertionError();
     }
      ... 
 }

答案 4 :(得分:2)

我宁愿使用枚举来保存字符串。这将确保无论您在何处使用该字符串,您只能在其中一个允许的字符串中传递。

答案 5 :(得分:2)

如果在这种情况下添加私有构造函数,则没有性能或内存开销。同样,由于您的公共静态变量在对象的所有实例之间共享,因此不需要它。

答案 6 :(得分:1)

如果您的类只有静态成员,则不需要私有或公共构造函数。即使没有对象,也可以访问所有成员。事实上,我发现在这种情况下有一个构造函数会让人感到困惑。

答案 7 :(得分:0)

合成公共构造函数将以任何方式生成。所以没有。

在运行时,数以亿计的几个字节实际上并没有多大差别。

我还建议创建类final,只是为了完整性,构造函数会抛出异常。

如果你想要简洁的源代码,你可以创建一个没有值的枚举。可能会引起初学者程序员的困惑。

答案 8 :(得分:0)

这是存储一些常量的正确方法,如Effective Java(第2版)第19项中所述。