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

cri*_*nge 15 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";
  ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

UPDATE

我正在寻找一个带有私有构造函数和类的描述性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";
  ...
}
Run Code Online (Sandbox Code Playgroud)

Pau*_*Pau 10

对我来说,最好的解释是在《Effective Java》一书中:第 4 项:使用私有构造函数强制执行非实例化查看更多

总之:

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

从定义上来说,最好的方法如下:

public class MyStrings {

     private MyStrings () {
       throw new AssertionError();
     }
      ... 
 }
Run Code Online (Sandbox Code Playgroud)


gmh*_*mhk 9

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

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

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


Lar*_*ren 7

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

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

public enum MyStrings {

  ONE ("something"),

  TWO ("something else");

  private String value;

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

}
Run Code Online (Sandbox Code Playgroud)

另一个选择是将它放在一个abstract类中,那些不能被实例化:

public abstract MyStrings {

  public static final String STUFF = "stuff";
  public static final String OTHER = "other stuff";
}
Run Code Online (Sandbox Code Playgroud)

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

MyStrings.STUFF
Run Code Online (Sandbox Code Playgroud)


小智 5

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

public abstract class MyStrings {
  public static final String ONE = "something";
  public static final String TWO = "another";
}
Run Code Online (Sandbox Code Playgroud)

并访问这样的静态变量

String val1 = MyStrings.ONE;
String val2 = MyStrings.TWO;
Run Code Online (Sandbox Code Playgroud)

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

  • 但是你仍然可以扩展这个类,这可以在最后一堂课中被阻止.然后添加私有构造函数也会阻止实例,然后你就完成了. (2认同)