代码之家  ›  专栏  ›  技术社区  ›  cringe

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

  •  14
  • cringe  · 技术社区  · 15 年前

    现在我正在考虑向一个只包含一些 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 回复  |  直到 6 年前
        1
  •  8
  •   Adam Azad    6 年前

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

    有几种方法可以考虑用户为了创建常量而阻止实例化

    1. 正如您所提到的,一个带有私有构造函数的类拥有所有字符串常量,这是一种方法,即使存在开销,也可以忽略不计。
    2. 否则,可以创建一个带有final修饰符的类并定义字符串常量
    3. 可以将抽象类与字符串常量一起使用
    4. 您可以在属性文件中定义字符串常量并从中进行访问,这肯定会减少内存并增加代码的灵活性。
        2
  •  6
  •   Lars Andren    15 年前

    您可以添加一个私有构造函数,但还有另外两个选项。

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

    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
    
        3
  •  5
  •   jweber    15 年前

    如果你不想让任何人把这个类的对象抽象成这样

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

    像这样访问静态变量

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

    我认为这是一个更好的解决办法。

        4
  •  2
  •   bert    15 年前

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

        5
  •  2
  •   Chris J    15 年前

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

        6
  •  1
  •   kgiannakakis    15 年前

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

        7
  •  1
  •   Pau    8 年前

    对我来说最好的解释是 通用程序设计 书: 第4项:使用私有构造函数强制不可实现性 ( See more )

    综上所述:

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

    确切地说,最好的方法是像下面这样:

    public class MyStrings {
    
         private MyStrings () {
           throw new AssertionError();
         }
          ... 
     }
    
        8
  •  0
  •   Tom Hawtin - tackline    15 年前

    任何方式都会生成一个合成的公共构造函数。所以没有。

    实际上,运行时数亿字节中的几个字节不会有太大影响。

    我也建议你去上课 final 为了完整起见,让构造函数抛出一个异常。

    如果您想简化源代码,可以创建一个没有值的枚举。可能会让初学者感到困惑。

        9
  •  0
  •   b_erb    15 年前

    这是存储一些常量的正确方法,正如在有效Java(第二版)中所建议的,项目19。