Java 使用私有构造函数来防止类的实例化?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2743434/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use of private constructor to prevent instantiation of class?
提问by cringe
Right now I'm thinking about adding a private constructor to a class that only holds some String
constants.
现在我正在考虑向一个只包含一些String
常量的类添加一个私有构造函数。
public class MyStrings {
// I want to add this:
private MyString() {}
public static final String ONE = "something";
public static final String TWO = "another";
...
}
Is there any performanceor memoryoverhead if I add a private constructor to this class to prevent someone to instantiate it?
如果我向此类添加私有构造函数以防止有人实例化它,是否有任何性能或内存开销?
Do you think it's necessary at all or that private constructors for this purpose are a waste of time and code clutter?
您认为这是完全必要的还是为此目的的私有构造函数是浪费时间和代码混乱?
UPDATE
更新
I'm going for a final class with private constructor and a descriptive javadoc for the class. I can't use a ENUM (which I'd prefer) because I'm stuck on Java 1.4 for now. This would be my modification:
我要为该类创建一个带有私有构造函数和一个描述性 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";
...
}
采纳答案by gmhk
Use of private constructor to prevent instantiation of class?
使用私有构造函数来防止类的实例化?
There are several ways you can think of users preventing from the Instantiations for the purpose of creating the Constants
您可以通过多种方式来考虑用户为了创建常量而阻止实例化
- As you have mentioned a class with the private Constructors and has all the string constants, is one way, even there is an overhead, that can be negligible
- Else you can create a Class with Final Modifier and Define your string constants
- You can use the Abstract Class with the String Constants
- You can define the string constants in the properties files and can access from that, this will definitely reduce the memory and increase the flexibility of your code.
- 正如您所提到的具有私有构造函数的类并具有所有字符串常量,这是一种方法,即使有开销,也可以忽略不计
- 否则,您可以使用 Final Modifier 创建一个类并定义您的字符串常量
- 您可以将抽象类与字符串常量一起使用
- 您可以在属性文件中定义字符串常量并可以从中访问,这肯定会减少内存并增加代码的灵活性。
回答by Tom Hawtin - tackline
A synthetic public constructor would have been generated any way. So no.
一个合成的公共构造函数会以任何方式生成。所以不行。
Really a few bytes out of hundreds of millions at runtime isn't going to make much difference.
实际上,在运行时数亿中的几个字节不会产生太大影响。
I also suggest making the class final
and just for completeness have the constructor throw an exception.
我还建议创建类final
,只是为了完整起见,让构造函数抛出异常。
If you want terse source code, you could create an enum with no values. Might cause some confusion with beginner programmers though.
如果您想要简洁的源代码,您可以创建一个没有值的枚举。不过可能会引起初学者的一些困惑。
回答by bert
I would rather use an enum to hold that Strings. This would ensure that wherever you use that Strings, you only get passed in one of the allowed Strings.
我宁愿使用枚举来保存该字符串。这将确保无论您在何处使用该字符串,都只会传入允许的字符串之一。
回答by b_erb
That's the right way to store some constants, as also suggested in Effective Java (2nd Ed.), item 19.
这是存储某些常量的正确方法,正如 Effective Java(第 2 版)第 19 项中所建议的那样。
回答by kgiannakakis
If your class has only static members, then there is no need to have a private or public constructor. All members are accessible even without an object. In fact I find it confusing to have a constructor in such a case.
如果您的类只有静态成员,则不需要私有或公共构造函数。即使没有对象也可以访问所有成员。事实上,我觉得在这种情况下有一个构造函数很令人困惑。
回答by jweber
If you don't won't anyone to make an object of the class you could make it abstract like this
如果你不想让任何人创建类的对象,你可以像这样使它抽象
public abstract class MyStrings {
public static final String ONE = "something";
public static final String TWO = "another";
}
and access your static variables like this
并像这样访问您的静态变量
String val1 = MyStrings.ONE;
String val2 = MyStrings.TWO;
I think this would be a nicer solution.
我认为这将是一个更好的解决方案。
回答by Lars Andren
You could add a private constructor, but there are two other options.
您可以添加私有构造函数,但还有另外两个选项。
In the same situation I would use an enumerator. If it makes sense to your implementation, you could use that instead, if it's public
or private
depends on where you need to use it:
在同样的情况下,我会使用枚举器。如果它对您的实现有意义,您可以改用它,如果它是public
或private
取决于您需要在何处使用它:
public enum MyStrings {
ONE ("something"),
TWO ("something else");
private String value;
private MyStrings(String str) {
this.value = str;
}
}
Another option would be to put it in an abstract
class, those can not be instantiated:
另一种选择是把它放在一个abstract
类中,那些不能被实例化:
public abstract MyStrings {
public static final String STUFF = "stuff";
public static final String OTHER = "other stuff";
}
Access for both enumerator and abstract class works just like with the implementation you presented:
对枚举器和抽象类的访问就像您提供的实现一样:
MyStrings.STUFF
回答by Chris J
There is no performance or memory overhead if you add a private constructor in this case. As well, it is not needed since your public static variables are shared among all instances of your object.
如果在这种情况下添加私有构造函数,则没有性能或内存开销。同样,也不需要它,因为您的公共静态变量在对象的所有实例之间共享。
回答by Pau
For me the best explanation is in Effective Javabook: Item 4: Enforce noninstantiability with a private constructor(See more)
对我来说,最好的解释是在Effective Java书中:第 4 项:使用私有构造函数强制不可实例化(查看更多)
In Summary:
总之:
- Private constructor is due utility classeswere not designed to be instantiated, so is a design decision. (NO performance or memory overhead)
- Making a class abstract doesn't work because can be subclassed and then instantiated.
- With an abstract class the user may think the class is for inheritance.
- The only way to ensure no instantiation is to add a
private constructor
which ensures the default constructor is not generated. - Private constructor prevents inheritance because the super constructor cannot be called (so it is not need the declare the class as final)
- Throw an error in the private constructor avoids call it within the class.
- 私有构造函数是由于实用程序类不是为了实例化而设计的,因此是设计决策。(没有性能或内存开销)
- 使类抽象不起作用,因为可以子类化然后实例化。
- 对于抽象类,用户可能认为该类用于继承。
- 确保没有实例化的唯一方法是添加一个
private constructor
以确保不会生成默认构造函数。 - 私有构造函数阻止继承,因为无法调用超级构造函数(因此不需要将类声明为 final)
- 在私有构造函数中抛出错误避免在类中调用它。
Definetively, the best way would be something like next:
明确地说,最好的方法是下一个:
public class MyStrings {
private MyStrings () {
throw new AssertionError();
}
...
}