public class DBSingleton {
private static DBSingleton instance = new DBSingleton();
private DBSingleton() {
// why do we need this constructor
}
public static DBSingleton getInstance() {
return instance;
}
}
How private constructor can help me?
I mean all variables and methods are static and even if I leave constructor public it will not change anything.
lets say someone create an object of my singleton nothing will happen because everything inside this class is static which means associated with the class itself not with object. Java static property is shared to all objects.
can anyone give me reasonable example please
You need a private constructor to prevent user from instantiating your class.
If you make your constructor public, users could do DBSingleton singleton = new DBSingleton() and your class will not be a Singleton!
A singleton class (edit: compare with singleton instance - see comments) doesn't even necessarily need to be instantiated; it's enough to give it a private constructor and declare all other methods static, forcing the user to invoke them on the class.
The constructor has to be private in order to ensure the class is a singleton, whether or not you create a single instance of it. If no private constructor were declared, Java would automatically provide a public no-arg constructor for it.
The class needs to be a single instance presumably for safety, namely, in cases where you want to invoke methods on it that do exactly what that singleton says they do. If you have an instance of a class that isn't explicitly made a singleton, then there's no guarantee when you invoke methods on it that it's running the singleton's implementation, because you might in fact have a subclass of DBSingleton in which said method is overridden. (If you invoke them as DBSingleton.someMethod(), you will of course get the expected behavior, but if you're doing this:
DBSingleton dbsInstance = DBSingleton.getInstance();
// ... all sorts of code, some of which might affect dbsInstance
dbsInstance.someMethod();
all bets are off.)
The more proper way to declare a class to avoid other instances of it is to declare it final. You give it a private constructor so that it also cannot be instantiated. (Either a final class or a class with a private constructor (or rather, zero non-private constructors) suffices to make the class non-overrideable.)
Related
Is it a right/recommended practice to add a private no-args constructor (which does nothing) for a class with only static utility methods and no instance variable (completely stateless)?
My reasoning for same is, i want to avoid any client using this class by instantiating it and always want this class's methods to be accessed in static fashion. Private constructor helps me adding this restriction on my utility classes.
Also i am defining my static classes as final, to avoid any client extending them; is it a right practice?
Yes.
To make sure no one instantiating it is best practice to define an private no args constructor which throw an IllegalStateException.
For example, for StringUtils class I would define the following constructor:
private StringUtils() {
throw new IllegalStateException("StringUtils class");
}
I have been programming java professionally for more than ten years. This is one of the weirdest bugs I've ever tried to track down. I have a private member, I initialize it and then it changes to null all by itself.
public class MyObject extends MyParent
{
private SomeOtherClass member = null;
public MyObject()
{
super();
}
public void callbackFromParentInit()
{
member = new SomeOtherClass();
System.out.println("proof member initialized: " + member);
}
public SomeOtherClass getMember()
{
System.out.println("in getMember: " + member);
return member;
}
}
Output:
proof member initialized: SomeOtherClass#2a05ad6d
in getMember: null
If you run this code, obviously it will work properly. In my actual code there are only these three occurrences (five if you count the printlns) in this exact pattern.
Have I come across some bug in the JVM? Unless I'm wrong, the parent class can't interfere with a private member, and no matter what I put between the lines of code I've shown you, I can't change the value of member without using the identifier "member".
This happens because of the order in which member variables are initialized and constructors are called.
You are calling callbackFromParentInit() from the constructor of the superclass MyParent.
When this method is called, it will set member. But after that, the subclass part of the object initialization is performed, and the initializer for member is executed, which sets member to null.
See, for example:
What's wrong with overridable method calls in constructors?
State of Derived class object when Base class constructor calls overridden method in Java
Using abstract init() function in abstract class's constructor
In what order constructors are called and fields are initialized is described in paragraph 12.5 of the Java Language Specification.
Assignment of null to field member happens after executing parent constructor.
The fix is to change:
private SomeOtherClass member = null;
to:
private SomeOtherClass member;
Never, never ever call a non final method from the superclass' constructor.
It's considered bad practice, precisely because it can lead to nasty, hard-to-debug errors like the one you're suffering.
Perform initialization of a class X within X's constructor. Don't rely on java's initialization order for hierarchies. If you can't initialize the class property i.e. because it has dependencies, use either the builder or the factory pattern.
Here, the subclass is resetting the attribute member to null, due to superclass and subclass constructors and initializer block execution order, in which, as already mentioned, you shouldn't rely.
Please refer to this related question for concepts regarding constructors, hierarchies and implicit escaping of the this reference.
I can only think about sticking to a (maybe incomplete) set of rules/principles to avoid this problem and others alike:
Only call private methods from within the constructor
If you like adrenaline and want to call protected methods from within the constructor, do it, but declare these methods as final, so that they cannot be overriden by subclasses
Never create inner classes in the constructor, either anonymous, local, static or non-static
In the constructor, don't pass this directly as an argument to anything
Avoid any transitive combination of the rules above, i.e. don't create an anonymous inner class in a private or protected final method that is invoked from within the constructor
Use the constructor to just construct an instance of the class, and let it only initialize attributes of the class, either with default values or with provided arguments
I've got a singleton class, which functions perfectly fine. I now just wonder what the last method is for?
public class PicassoSingleton {
private static Picasso instance;
public static Picasso with(Context context) {
if (instance == null) {
instance = new Picasso.Builder(context.getApplicationContext()).debugging(true).downloader(new ImageDownloader(context)).build();
}
return instance;
}
private PicassoSingleton() {
throw new AssertionError("No instances.");
}
}
Does anybody know what it does or what the use is?
Normally it would be enough to make the constructor private to prevent others classes from instantiating a PicassoSingleton.
Throwing an exception in the private constructor seems to be paranoid programming, because the implementor of a class knows it's internal details and must know what he does.
But there is one reason when it makes sense. Throwing an exception in the constructor will also prevent others from using reflection to instantiate an object of the class.
This will be impossible
Constructor<PicassoSingleton> constructor = PicassoSingleton.class.getDeclaredConstructor();
constructor.setAccessible(true);
constructor.newInstance(); // will throw the AssertionError - impossible to instantiate it
It prevents the class from being instantiated, if you have no constructor specified then all classes by default can have a new instance created using new PicassoSingleton() with no arguments.
If you specify a constructor and make it private then only the class itself can create instances of itself. If you then throw an exception inside the constructor not even the class can instantiate itself and it prevents people using reflection from doing so.
Doing this essentially means that the class can provide static methods, variables, etc but can never be used as an object (unless you provide another constructor, in which case the access levels of that constructor may allow it to be used).
That's the constructor for the PicassoSingleton class. It's private to make sure you can't call it from other code. Instead, you use the with method to obtain the singleton instance of the class.
private PicassoSingleton() {
throw new AssertionError("No instances.");
}
Constructor is made private so that no new instances of the class can be created using new keyword.
PicassoSingleton is a constructor here and by making it private you are restricting other class to instantiate this.
This make the constructor unavailable to other classes and an instance of this class can only be accessed via getInstance method.
In additional to Tim B answer I want to say that, not only that you prevent this class from been used as object, you also prevent other classes to extend it.
How ever you do not have to throw exception in the constructor you can just leave it blank, the only reason to do it is protection from your self.
public static Picasso with(Context context) {
if (instance == null) {
instance = new Picasso.Builder(context.getApplicationContext()).debugging(true).downloader(new ImageDownloader(context)).build();
}
return instance;
}
this method is use to access private field "instance" and it is static bcoz then you can directly access it with its class name without making objects. and it is a public method because you may need to access it from outside of the current package. initially it is check whether instance variable is null or not. if null, then it is not already initiated. then it will create a new Object and initiate it. and finally return the instance object reference. this kind of methods are called accessior methods in programming.
private PicassoSingleton() {
throw new AssertionError("No instances.");
}
this is the constructor of the PicassoSingleton class. according to theory of Singleton design pattern definition, it should not allow to make objects of the class. to do it we can make a private constructor. private modifier is access only within the same class. So at the developing time someone mistakenly create a instance to this class it will throw a Assertion Error by telling "No Instances"
hope you get what i mean.
finally one word about class field
private static Picasso instance;
this object reference variable is to hold the object reference. and it is private to limit the access from outside of the class. and it is static reference bocz it is access from static method.
Using Java reflection, one can instantiate an object of a class, even via a private constructor, e.g. for
public class MyClass
{
private MyClass(Object p1, String p2)
{
// Constructor with no modifications to static code
}
}
one can do (in the same or any other class, exception handling omitted for simplification)
public static final Constructor myClass;
static
{
myClass = MyClass.class.getConstructor(Object.class, String.class);
myClass.setAccessible(true);
}
and then create new instances of MyClass like
myClass.newInstance(new Object(), "Test");
Is the above call to newInstance() thread-safe, given that myClass is static?
Calling Constructor.newInstance() does not seem to be strictly thread-safe; at least in my openjdk-6 implementation I find a class sun.reflect.NativeConstructorAccessorImpl having a field defined as private int numInvocations; and later on this line of code: if (++numInvocations > ReflectionFactory.inflationThreshold()) { - which may certainly behave otherwise as expected.
Also, in the Constructor class itself, the method acquireConstructorAccessor() is documented with "NOTE that there is no synchronization used here".
But the dodgy behaviour does not seem to result in an overall unexpected behavior, only doing things repeatedly/unnecessarily, thus calling newInstance() in parallel would NOT result in something being screwed up.
Obviously, you can still mess things up with what's done within the instance constructor.
Yes, the class instance is static, and the constructor is thread safe, as long as it is not doing anything non-thread safe with the static context of the object.
This question already has an answer here:
Correct way to prevent instantiation in Java [closed]
(1 answer)
Closed 9 years ago.
Short:
Do I need to do something else but leaving out constructor?
Long:
I want to implement class which cannot be instantiate. I have find example in Math class here: http://docs.oracle.com/javase/6/docs/api/java/lang/Math.html
So I would write same thing:
public final class MyClass{
public static int doubleMe(int x){
return 2*x;
}
}
Constructor is absent, so instantiation should be impossible.
But I am not sure about making my class final. Maybe (not necessarily) I would like to extend it in the future (eg. public class myClassB extends myClass) and this keyword will prevent it - so does it have to be there?.
Do I need to do something else but leaving out constructor?
Yes. If you don't write a constructor yourself, Java will provide one.
You need to write your own private constructor:
public final class MyClass {
// Prevent the compiler from supplying a constructor automatically.
private MyClass() {}
public static int doubleMe(int x){
return 2*x;
}
}
(I've fixed the name of your class to follow normal Java naming conventions.)
If you look at the source code for java.lang.Math you'll find a private constructor there for the same reason.
But I am not sure about making my class final. Maybe (not necessarily) I would like to extend it in the future (eg. public class myClassB extends myClass) and this keyword will prevent it - so does it have to be there?.
You should only extend your class for reasons of polymorphism - which aren't relevant for a class which can't be instantiated.
Constructor is absent, so instantiation should be impossible.
No - if there is no constructor declared, then Java automatically gives the class an implicit default constructor, with no formal arguments and no throws clause (JLS §8.8.9). You need to explicitly declare a private constructor in order to make the class impossible to instantiate from the outside. Now as for your second concern: it makes no sense to extend a class that is impossible to instantiate, and hence it would make sense to declare your class as final - although this is not a requirement for making it un-instantiateable.
You might find the following section of the JLS relevant: §8.8.10: Preventing Instantiation of a Class.
In addition to making every method static, mark the class as abstract. This will prevent it from being instantiated.
abstract public class MyClass {
...
}
Creating a private constructor will prevent classes outside MyClass from constructing it, but won't stop one of the methods from within MyClass from doing it (private constructors are visible to the class itself).
Use abstract instead of final.
Use one (well, actually as many as you like) constructor and throw an unchecked exception from it.
Nobody will ever be able to create an instance of such a class.
Though, they can use static methods/fields of the class.
The approach sounds barbarian, but formally it will work.