使用私有构造函数来防止类的实例化?
现在,我正在考虑将私有构造函数添加到只包含某些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";
...
}
使用私有构造函数来防止类的实例化?
有正如你所提到的一类的私有构造函数且所有的字符串contants你可以认为用户从实例化防止用于创建常量
- 目的的几种方式,是一个这样,即使有1A中的开销,可以忽略不计
- 否则,您可以创建一个类具有最终Modidifier并定义字符串常量
- 您可以使用抽象类与字符串常量
- 您可以在属性文件中定义字符串常量,并可以从中访问,这将明确地减少内存并增加代码的灵活性。
合成的公共构造函数会以任何方式生成。所以不行。
在运行时真的只有几亿字节不会有太大的变化。
我也建议让类final
,只是为了完整性构造函数抛出一个异常。
如果你想简化源代码,你可以创建一个没有值的枚举。尽管如此,可能会引起初学者程序员的混淆。
的Java只合成一个默认的公共构造函数。私有构造函数阻止生成默认值。 – 2010-04-30 09:46:08
我宁愿使用枚举来保存字符串。这将确保无论您使用该字符串的哪个位置,都只能通过允许的字符串之一。
这就是存储一些常量的正确方法,在有效的Java(第2版)还建议,项目19
如果你的类只有静态成员,那么就没有必要有一个私人或公共构造函数。即使没有物体,所有成员都可以访问。事实上,我发现在这种情况下有一个构造函数令人困惑。
如果你根本没有构造函数,编译器会为你提供一个 - 它将被公开,允许人们构造一个实例。私有构造函数的目的是防止这种情况。 – 2010-04-30 09:17:00
@Jon在提供的场景中没有给出所有成员都是静态和最终的点。用这个类的实例没有太多的工作可做,所以阻止它被实例化是没有意义的IMO。那么,它会阻止某人使用扩展类,但是一个“最终”类可以解决这个问题。 – jweyrich 2010-04-30 09:27:38
@jweyrich:阻止它被实例化的一点是你不应该*允许用户做一些毫无意义的事情。 (这就是为什么C#中存在静态类的原因。)如果没有创建类的实例的目的,那么你的代码应该阻止它发生。一个注释为“//防止实例化”的简单私有构造函数是很好的IMO。 – 2010-04-30 09:36:59
如果不将没有人使类的一个对象,你可以把它抽象这样
public abstract class MyStrings {
public static final String ONE = "something";
public static final String TWO = "another";
}
,并访问您的静态变量这样
String val1 = MyStrings.ONE;
String val2 = MyStrings.TWO;
我想这将是一个更好的解决方案。
但是你仍然可以扩展课程,这可以在最后一堂课中预防。然后添加私有构造函数也会阻止实例,然后完成。 – 2010-04-30 09:22:56
是的,你说得对,它可以延长,你有一个点。我还没有关于这个,最终的类和私人构造函数的解决方案。 – jweber 2010-04-30 09:36:28
我会用这种方法。如果有人不厌其烦地扩展抽象类并将其实例化,那么他肯定有充分的理由这样做。 – 2010-04-30 09:38:12
您可以添加一个私有构造函数,但还有两个其他选项。
在相同的情况下,我会使用一个枚举器。如果是有意义的您的实现,你可以用它来代替,如果是public
或private
取决于你需要使用它:
public enum MyStrings {
ONE ("something"),
TWO ("something else");
private String value;
private MyStrings(String str) {
this.value = str;
}
}
另一种办法是把它放在一个abstract
类,那些不能被实例化:
两个枚举和抽象类访问工作就像你提出的实现:
MyStrings.STUFF
我也认为使用枚举是去这里的方式。我也会覆盖toString方法。 – Eldelshell 2010-04-30 09:44:31
啊,我忘了提到这个类是用于Java 1.4的。我想在1.5以上,但你知道,你并不总是得到你想要的东西... ;-) 我会去ENUM和一个最新的Java类的新版本。 – cringe 2010-05-03 06:06:20
如果在这种情况下添加私有构造函数,则没有性能或内存开销。而且,它不是必需的,因为你的公共静态变量是在你的对象的所有实例*享的。
对我来说,最好的解释是有效的Java书:项目4:强制noninstantiability与私有构造(See more)
总结:
- 私有构造是由于实用程序类不是为了实例化而设计的,因此是设计决策。 (没有性能或内存开销)
- 使类抽象不起作用,因为可以被子类化,然后实例化。
- 对于抽象类,用户可能认为该类用于继承。
- 确保没有实例化的唯一方法是添加一个
private constructor
,以确保未生成默认构造函数。 - 私人构造函数阻止继承,因为超级构造函数不能被调用(所以它不需要声明类作为final)
- 在私有构造函数中抛出一个错误避免在类中调用它。
Definetively,最好的办法是这样的未来:
public class MyStrings {
private MyStrings() {
throw new AssertionError();
}
...
}
更新区块是一个答案,如果有* *没有人 – 030 2018-02-19 22:02:35