2010-04-30 160 views
14

现在,我正在考虑将私有构造函数添加到只包含某些String常量的类。使用私有构造函数来防止类的实例化?

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

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

是否有任何性能内存开销,如果我添加一个私有构造函数,这个类来防止有人实例呢?

你认为这是必要的吗?或者私人构造函数为此目的是浪费时间和代码混乱?

UPDATE

我要与私有构造函数和类的描述性的javadoc final类。我不能使用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"; 
    ... 
} 
+0

更新区块是一个答案,如果有* *没有人 – 030 2018-02-19 22:02:35

回答

7

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

有正如你所提到的一类的私有构造函数且所有的字符串contants你可以认为用户从实例化防止用于创建常量

  1. 目的的几种方式,是一个这样,即使有1A中的开销,可以忽略不计
  2. 否则,您可以创建一个类具有最终Modidifier并定义字符串常量
  3. 您可以使用抽象类与字符串常量
  4. 您可以在属性文件中定义字符串常量,并可以从中访问,这将明确地减少内存并增加代码的灵活性。
0

合成的公共构造函数会以任何方式生成。所以不行。

在运行时真的只有几亿字节不会有太大的变化。

我也建议让类final,只是为了完整性构造函数抛出一个异常。

如果你想简化源代码,你可以创建一个没有值的枚举。尽管如此,可能会引起初学者程序员的混淆。

+1

的Java只合成一个默认的公共构造函数。私有构造函数阻止生成默认值。 – 2010-04-30 09:46:08

2

我宁愿使用枚举来保存字符串。这将确保无论您使用该字符串的哪个位置,都只能通过允许的字符串之一。

0

这就是存储一些常量的正确方法,在有效的Java(第2版)还建议,项目19

1

如果你的类只有静态成员,那么就没有必要有一个私人或公共构造函数。即使没有物体,所有成员都可以访问。事实上,我发现在这种情况下有一个构造函数令人困惑。

+10

如果你根本没有构造函数,编译器会为你提供一个 - 它将被公开,允许人们构造一个实例。私有构造函数的目的是防止这种情况。 – 2010-04-30 09:17:00

+1

@Jon在提供的场景中没有给出所有成员都是静态和最终的点。用这个类的实例没有太多的工作可做,所以阻止它被实例化是没有意义的IMO。那么,它会阻止某人使用扩展类,但是一个“最终”类可以解决这个问题。 – jweyrich 2010-04-30 09:27:38

+4

@jweyrich:阻止它被实例化的一点是你不应该*允许用户做一些毫无意义的事情。 (这就是为什么C#中存在静态类的原因。)如果没有创建类的实例的目的,那么你的代码应该阻止它发生。一个注释为“//防止实例化”的简单私有构造函数是很好的IMO。 – 2010-04-30 09:36:59

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; 

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

+2

但是你仍然可以扩展课程,这可以在最后一堂课中预防。然后添加私有构造函数也会阻止实例,然后完成。 – 2010-04-30 09:22:56

+0

是的,你说得对,它可以延长,你有一个点。我还没有关于这个,最终的类和私人构造函数的解决方案。 – jweber 2010-04-30 09:36:28

+0

我会用这种方法。如果有人不厌其烦地扩展抽象类并将其实例化,那么他肯定有充分的理由这样做。 – 2010-04-30 09:38:12

6

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

在相同的情况下,我会使用一个枚举器。如果是有意义的您的实现,你可以用它来代替,如果是publicprivate取决于你需要使用它:

public enum MyStrings { 

    ONE ("something"), 

    TWO ("something else"); 

    private String value; 

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

} 

另一种办法是把它放在一个abstract类,那些不能被实例化:

​​

两个枚举和抽象类访问工作就像你提出的实现:

MyStrings.STUFF 
+1

我也认为使用枚举是去这里的方式。我也会覆盖toString方法。 – Eldelshell 2010-04-30 09:44:31

+0

啊,我忘了提到这个类是用于Java 1.4的。我想在1.5以上,但你知道,你并不总是得到你想要的东西... ;-) 我会去ENUM和一个最新的Java类的新版本。 – cringe 2010-05-03 06:06:20

2

如果在这种情况下添加私有构造函数,则没有性能或内存开销。而且,它不是必需的,因为你的公共静态变量是在你的对象的所有实例中共享的。

0

对我来说,最好的解释是有效的Java书:项目4:强制noninstantiability与私有构造See more

总结:

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

Definetively,最好的办法是这样的未来:

public class MyStrings { 

    private MyStrings() { 
     throw new AssertionError(); 
    } 
     ... 
} 
相关问题