Preventing call of a private constructor from within the class in Java
We can restrict the creation of object of a class by making its constructor private. But this constructor could still be called from within the class. Is the开发者_StackOverflow社区re any way to prevent this in Java?
Thanks.
No, there is no clean way to do this. And really I cannot see a reason to do so. Because if the constructor is private, this means that he can only be called from code within this exact class (no subclasses, or other classes in the package), so if you do not want the constructor to be called, put a comment on it which says so.
Since everyone who is able to use the constructor would be able to remove any measures you put there to prevent the calling of the constructor, it would have no real effect.
Besides, if you need a singleton, then you may want the constructor to be run at least once (except if your idea of a singleton is a purely static class).
If it's private, and you don't want it called within its own class, there's an easy way to prevent such a thing: Don't write the code that calls it more than once. You're the author of the class. Why would you write code to prevent you yourself from doing something that is within your control?
It can't be called outside the class without resorting to reflection. If you don't want it called more than once within the class, then just don't do it. Why write code to prevent an action that you can choose not to do?
Let's review:
We can resrict the creation of object of a class by making its constructor private.
Constructor is private, so it can't be called outside the class unless a client uses the reflection API to undermine access restrictions.
But this constructor could still be called from within the class. Is there anyway to prevent this in Java?
The OP is asking to prevent calling the restricted constructor inside the class.
If these two statements are correct, please explain why there needs to be logic preventing calls to the constructor.
Here's a typical use of a private constructor:
public class Singleton
{
private static final Singleton instance = new Singleton();
public static void main(String[] args)
{
Singleton singleton = Singleton.getInstance();
System.out.println(singleton);
}
private Singleton() {};
public static Singleton getInstance() { return Singleton.instance; }
public String toString() { return Singleton.class.getName(); }
}
I can't see the point of disallowing the call to the private constructor.
The official answer is no. If anybody can get private access to your class he can instantiate it.
However you can do this:
private static int count = 0;
private MyClass(){
if(++count>1)throw new IllegalStateException(); //allow exactly one instantiation
}
No, there is no way to enforce a single instance of a particular type. The closest you can come is, as you describe, making the constructor private so that only functions within that class can call it. You could do something at runtime (such as throwing an exception if your static instance already exists), but that wouldn't get you anything at compile time.
If you're making a singleton, enums are the best way to go:
public enum MySingleton {
INSTANCE;
// add methods & stuff here
}
// Usage:
MySingleton.INSTANCE.doSomething();
The "singletonicity" is guaranteed by the JVM - there'll only be one instance.
Yes, there is a simple way: just make the private constructor throw an exception:
class MyStaticFunctions {
private MyStaticFunctions() {
throw new UnsupportedOperationException("do not instantiate");
}
}
Note that my answer is different because I am interpreting the question slightly differently from most of the other answers listed. Many other answers assumed you want the class to be a singleton, in which case the constructor needs to be called exactly once. I am assuming that you don't want any instances of the class, so the constructor should be called 0 times.
精彩评论