Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singleton Pattern

Tags:

java

singleton

This question, like my previous question, references Effective Java. This time I have quite a few sub-questions.

  1. A privileged client can invoke the private constructor reflectively with the aid of the AccessibleObject.setAccessible() method. If you need to defend against this, modify the constructor.
    How, exactly, can a private constructor be invoked? And what is AccessibleObject.setAccessible()?

  2. What approach do you experts follow with singletons?

    // Approach A
    public class Test{
        public static final Test TestInstance = new Test();
        private Test(){ ... }
        .
        .
        .
    }
    
    
    // Approach B
    public class Test{
        private static final Test TestInstance = new Test();
        private Test(){ ... }
        public static Test getInstance() { return TestInstance; }
        .
        .
        .
    }
    

    Isn't the second approach more flexible, in case we have to make a check for new instances every time or the same instance every time?

  3. What if I try to clone the class/object?

  4. a single-element enum type is the best way to implement a singleton.
    Why? How?

like image 589
t0mcat Avatar asked Nov 02 '10 19:11

t0mcat


3 Answers

A priviledged cleint can invoke the private constructor reflectively with the aid of the AccessibleObject.setAccessible method, If you need to defend this, modify the constructor. My question is: How exactly can a private constructor is invoked? and what is AccessibleObject.setAccessible??

Obviously a private constructor can be invoked by the class itself (e.g. from a static factory method). Reflectively, what Bloch is talking about is this:

import java.lang.reflect.Constructor;

public class PrivateInvoker {
    public static void main(String[] args) throws Exception{
        //compile error 
//      Private p = new Private();

        //works fine
        Constructor<?> con = Private.class.getDeclaredConstructors()[0];
        con.setAccessible(true);
        Private p = (Private) con.newInstance();
    } 
}

class Private {
    private Private() {
        System.out.println("Hello!");
    } 
}

2.What approach do you experts follow with singletons:

...

Typically, the first is favoured. The second (assuming you were to test if TestInstance is null before returning a new instance) gains lazy-loading at the cost of needing to be synchronized or being thread-unsafe.

I wrote the above when your second example didn't assign the instance to TestInstance at declaration. As stated now, the above consideration is irrelevant.

Isn't the second approach more flexible in case we have to make a check for new instance every time or same instance every time?

It's not about flexibility, it's about when the cost of creating the one (and only) instance is incurred. If you do option a) it's incurred at class loading time. That's typically fine since the class is only loaded once it's needed anyway.

I wrote the above when your second example didn't assign the instance to TestInstance at declaration. As stated now, in both cases the Singleton will be created at class load.

What if I try to clone the class/object?

A singleton should not allow cloning for obvious reasons. A CloneNotSupportedException should be thrown, and will be automatically unless you for some reason implement Cloneable.

a single-element enum type is the best way to implement a singleton. Why? and How?

Examples for this are in the book, as are justifications. What part didn't you understand?

like image 145
Mark Peters Avatar answered Nov 16 '22 12:11

Mark Peters


Singletons are a good pattern to learn, especially as an introductory design pattern. Beware, however, that they often end up being one of the most over-used patterns. It's gotten to the point that some consider them an "anti-pattern". The best advice is to "use them wisely."

For a great introduction to this, and many other useful patterns (personally, I find Strategy, Observer, and Command to be far more useful than Singleton), check out Head First Design Patterns.

like image 2
Visionary Software Solutions Avatar answered Nov 16 '22 12:11

Visionary Software Solutions


A priviledged cleint can invoke the private constructor reflectively with the aid of the AccessibleObject.setAccessible method, If you need to defend this, modify the constructor. My question is: How exactly can a private constructor is invoked? and what is AccessibleObject.setAccessible??

You can use java reflection to call private constructors.

What approach do you experts follow with singletons:

I am a fan of using enum to actually do this. This is in the book also. If that's not an option, it is much simpler to do option a because you don't have to check or worry about instance being already created.

What if I try to clone the class/object?

Not sure what you mean? do you mean clone() or something else that I don't know of?

a single-element enum type is the best way to implement a singleton. Why? and How?

Ahh my own answer. haha. This is the best way because in this case, the java programming language guarantees a singleton instead of the developer having to check for a singleton. It's almost as if the singleton was part of the framework/language.

Edit: I didn't see that it was a getter before. Updating my answer to this - it's better to use a function such getInstance because you can control what happens through a getter but you can't do the same if everybody is using a reference directly instead. Think of the future. If you ended up doing SomeClass.INTANCE and then later you wanted to make it lazy so it doesn't load right away then you would need change this everywhere that its being used.

like image 2
Amir Raminfar Avatar answered Nov 16 '22 12:11

Amir Raminfar