Singleton Template

This question, like my previous question, refers to efficient Java. This time I have a lot of questions.

  • A privileged client can reference the private constructor reflexively using the AccessibleObject.setAccessible() method. If you need to guard against this, change the constructor.
    How, in fact, can you call a private constructor? And what is AccessibleObject.setAccessible() ?

  • What approach do you use in a single player business?

     // 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; } . . . } 

    Is the second approach more flexible if we have to check for new instances or the same instance each time?

  • What if I try to clone a class / object?

  • a singleton enumeration type is the best way to implement singleton.
    What for? How?

+6
java singleton
source share
5 answers

A privileged cleint can invoke a private constructor reflexively using the AccessibleObject.setAccessible method. If you need to protect this, change the constructor. My question is: how exactly can a private constructor be called? and what is AccessibleObject.setAccessible ??

Obviously, the private constructor can be called by the class itself (for example, from the static factory method). Reflectable, what Bloch says:

 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 take with experts in the following groups:

...

As a rule, preference is given to the first. The second (assuming you had to check if TestInstance is null before returning a new instance), gets lazy loading due to the need for synchronization or to be insecure.

I wrote above when your second example did not assign an instance of TestInstance when declaring. As indicated above, the above consideration is not relevant.

Is the second approach more flexible if we have to check a new instance each time or the same instance each time?

This is not about flexibility, but about when the cost of creating one (and only) instance will arise. If you do option a) it takes class loading time. This is usually great, as the class only loads after it is needed.

I wrote above when your second example did not assign an instance of TestInstance when declaring. As indicated now, in both cases, Singleton will be created when the class loads.

What if I try to clone a class / object?

The syntax should not allow cloning for obvious reasons. You need to throw a CloneNotSupportedException and it will be automatically if you for some reason do not implement Cloneable .

a singleton enumeration type is the best way to implement singleton. What for? And How?

Examples for this are given in the book, as well as justifications. Which part do you not understand?

+11
source share

A privileged cleint can invoke a private constructor reflexively using the AccessibleObject.setAccessible method. If you need to protect this, modify the constructor. My question is: how exactly can a private constructor be called? and what is AccessibleObject.setAccessible ??

You can use java reflection to call private constructors.

What approach do you use in a single player business?

I am a fan of using enum for this. This is also in the book. If this is not an option, it is much easier to make a choice because you do not need to check or worry that the created instance is already created.

What if I try to clone a class / object?

Not sure what you mean? do you mean clone () or something else i don't know about?

a singleton enumeration type is the best way to implement singleton. What for? And How?

Ah my own answer. haha This is the best way, because in this case, the Java programming language guarantees a single single instead of a developer who needs to test a singleton. It is almost as if the singleton was part of a framework / language.

Edit: Previously, I did not see that it was a getter. Updating my answer to this question is better to use the getInstance function, because you can control what happens through getter, but you cannot do the same if everyone uses the link directly. Think about the future. If you finished making SomeClass.INTANCE, and then later you wanted to make it lazy so that it does not load right away, you will need to change it wherever it is used.

+2
source share

Singletones are a good sample to learn, especially as an introductory design template. Beware, however, that they often turn out to be one of the most unused patterns . This went so far as to be considered by some as "anti-pattern . " The best advice is to "use them wisely."

For a great introduction to this and many other useful templates (I personally find Strategy, Observer and Command much more useful than Singleton), see Primary Design Templates .

+2
source share

The first rule of the Singleton (Anti-) pattern does not use it. The second rule does not use it to facilitate access to one instance of the class to which you want to share several other objects, especially if it is a dependency on these classes. Use dependency injection instead. There are valid uses for the Singletons, but people tend to abuse them badly because they are so easy to use. They make it difficult to test classes that depend on them, and make systems inflexible.

As for your questions, I think 1 , 2, and 3 can be answered by saying "use enum - singleton". Then you don’t need to worry about issues with constructor accessibility, clone() ing, etc. As for 4 , this is a good argument for them. I also have to ask if you read the section in Efficient Java that clearly answers your question?

+1
source share

Example singleton lazy init: class main:

 public class Main { public static void main(String[] args) { System.out.println(Singleton.getInstance("first").value); System.out.println(Singleton.getInstance("second").value); System.out.println(Singleton.getInstance("therd").value); } } 

Singleton class:

 public class Singleton { private static Singleton instance; public String value; private Singleton (String s){ this.value =s; } public static Singleton getInstance(String param) { if (instance == null) instance = new Singleton(param); return instance; } } 

When the application starts, the console will contain the following lines:

 first first first 

\ | / 73

0
source share

All Articles