0

I can still instantiate by using constructor although in class definition it has been declared as private constructor??? Here is code snippet:

public class Singleton {

  private static Singleton instance;
  private String name;

  /* Private constructor prevents other classes from instantiating */
  private Singleton(String name) {
    this.name = name;
    // Optional code
  }

  /*
   * Static factory method that creates instance instead of constructor.
   * Synchronization helps to block any attempt to instantiate from simultaneous
   * thread hence break concept of singleton.
   * This method uses a technique known as lazy instantiation.
   */
  public static synchronized Singleton getInstance(String name) {
    if (instance == null) {
      instance = new Singleton(name);
    }
    return instance;
  }

  /* Override Object clone method to avoid cloning */
  @Override
  public Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException();
  }

  public String getName() {
    return name;
  }

  /* Example of using singleton object */
  public static void main(String[] args) {
    Singleton a = new Singleton("Hoang");
    Singleton b = new Singleton("Shiha");
    System.out.println(a.getName());
    System.out.println(b.getName());
  }
3
  • Dude, put the time to post these things right and learn how to enter code samples. That stuff is almost unreadable. Commented Feb 11, 2011 at 12:36
  • You can get code formatted as code by putting four spaces before each line. Or select it and press the {} button. See the Markdown Editing Help page for more information. Commented Feb 11, 2011 at 12:40
  • You don't need to override clone(), it will throw an exception anyway. Commented Feb 11, 2011 at 12:41

4 Answers 4

6

You can still instantiate it because your test main() method, being in the same class, has access to the private constructor: private means "only available to this class".

Put your test in another class, and you'll get what you expect.

Sign up to request clarification or add additional context in comments.

1 Comment

You're welcome, we all make mistakes :-) I see you're new to Stack Overflow, the normal etiquette if this has satisfactorily answered your questions is to "accept answer" to mark it as resolved - and give the responder some tasty karma points :-)
1

Your test method is within the same class -> it has access to private members & methods.

Refer to this question for more info on the Singleton pattern in Java :)

Comments

1

You are able to instantiate the singleton because you are doing it from a method inside the Singleton's class definition (hint, you can access private methods within the class that define them.

Try doing that from outside your Singleton, and it will fail. On another note, Singleton are typically defined as final (very rare that you legitimately need to extend a Singleton class).


On another note, one typically puts some sort of guard condition (.ie. throwing a UnsupportedOperationException) on the default (and private) constructor to defend against accidental (or malicious attack) access to it via reflection.

  /* default constructor made private and defended against reflection access */
  private Singleton() {
    throw new UnsupportedOperationException("naughty boy");
  }

Comments

1

To be sure to instanciate it just once, you may use the Singleton Enum pattern:

public enum MySingleton {
    INSTANCE("My singleton name");

    private MySingleton(String name) {
        this.name = name;
    }

    private String name;
    public String getName() {
        return this.name;
    }
}

An enum is in some way a list of singletons sharing the same interface

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.