In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "how to destroy the singleton mode in Java". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Singleton pattern (Singleton Pattern) is one of the simplest design patterns in Java. Is a creative design pattern. It is defined as ensuring that there is only one instance of a class and providing a global access point to it.
The singleton pattern is generally reflected in the class declaration, where the singleton class is responsible for creating its own objects while ensuring that only a single object is created. This class provides a way to access its unique object directly without instantiating the object of the class.
But in fact, a single case is not completely safe, and it may be destroyed.
The following is the restoration of an interview site, the reason why we talked about this topic is because the interviewer asked me a lot of questions about the singleton model, and I answered it well, and then the interviewer casually asked, "is the singleton absolutely safe?" The following dialogue followed:
Q: is singleton mode absolutely safe?
A: (I know this question, don't try to baffle me) not necessarily, in fact, a single case can also be destroyed?
Q: Oh? How to say that ?
A: the singleton mode actually hides the constructor to ensure that the user cannot actively create an object. But in fact, we do have a way to destroy him.
Q: do you know any way to break the singleton?
A: there is a relatively simple way, and that is reflection.
A single case of reflection failure
Let's start with a more common singleton pattern:
Import java.io.Serializable; / * implement singleton * / public class Singleton implements Serializable {private volatile static Singleton singleton; private Singleton () {} public static Singleton getSingleton () {if (singleton = = null) {synchronized (Singleton.class) {if (singleton = = null) {singleton = new Singleton () } return singleton;}}
This singleton pattern provides a constructor of type private, and normally we cannot call an object's private method directly. But reflection technology provides us with a back door.
In the following code, we get the constructor of Singleton by reflection, set its access permission, and then create a new object through this method:
Import java.lang.reflect.Constructor; public class SingletonTest {public static void main (String [] args) {Singleton singleton = Singleton.getSingleton (); try {Class singleClass = (Class) Class.forName ("com.dev.interview.Singleton"); Constructor constructor = singleClass.getDeclaredConstructor (null); constructor.setAccessible (true); Singleton singletonByReflect = constructor.newInstance () System.out.println ("singleton:" + singleton); System.out.println ("singletonByReflect:" + singletonByReflect); System.out.println ("singleton = = singletonByReflect:" + (singleton = = singletonByReflect));} catch (Exception e) {e.printStackTrace ();}
The output is as follows:
Singleton: com.dev.interview.Singleton@55d56113 singletonByReflect: com.dev.interview.Singleton@148080bb singleton = = singletonByReflect: false
As mentioned above, a new singleton object can be obtained by launching, which destroys the singleton.
Q: is there any way to avoid this single case of destruction?
A: actually, we can, as long as we add some judgment to the constructor.
In the following way, we add the following code to the constructor of Singleton:
Private Singleton () {if (singleton! = null) {throw new RuntimeException ("Singleton constructor is called...");}}
In this way, when the constructor is called through reflection, an exception is thrown:
Caused by: java.lang.RuntimeException: Singleton constructor is called...
Serialization breakage singleton
Q: mm-hmm, it's pretty good, so let's change the question.
A: (this part of the interviewer hesitated to ask me any questions, and I volunteered to remind him.) in fact, in addition to reflection can destroy singletons, there is also another way.
Q: well, tell me what else you can do.
A: in fact, singletons can also be destroyed by serialization + deserialization.
As in the following code, we serialize the singleton object, save it to a temporary file, and then deserialize it from the temporary file:
Public class SingletonTest {public static void main (String [] args) {Singleton singleton = Singleton.getSingleton (); / / Write Obj to file ObjectOutputStream oos = null; try {oos = new ObjectOutputStream (new FileOutputStream ("tempFile")); oos.writeObject (singleton); / / Read Obj from file File file = new File ("tempFile") ObjectInputStream ois = new ObjectInputStream (new FileInputStream (file)); Singleton singletonBySerialize = (Singleton) ois.readObject (); / / determine whether it is the same object System.out.println ("singleton:" + singleton); System.out.println ("singletonBySerialize:" + singletonBySerialize); System.out.println ("singleton = = singletonBySerialize:" + (singleton = = singletonBySerialize)) } catch (Exception e) {e.printStackTrace ();}
The output is as follows:
Singleton: com.dev.interview.Singleton@617faa95 singletonBySerialize: com.dev.interview.Singleton@5d76b067 singleton = = singletonBySerialize: false
As above, a new singleton object can be obtained by serialization and then deserialization, which destroys the singleton.
Because serialization creates a new object by calling a parameterless constructor through reflection during object deserialization, singletons can also be destroyed by deserialization.
Q: is there any way to avoid this kind of damage to a single case?
A: yes, of course. Just modify the deserialization strategy.
You just need to add the readResolve method to the Sinleton and specify the generation strategy for the object to be returned in that method. That is, serialization adds the following code to the Singleton class:
Private Object readResolve () {return getSingleton ();}
Q: why does adding readResolve solve the problem of serialization breaking singletons?
A: because during deserialization, the ObjectInputStream#readOrdinaryObject method is executed during deserialization execution, this method determines whether the object contains a readResolve method, and if so, it calls this method directly to get the object instance.
Q: how do you create an object when deserializing without the readResolve method?
A: it's a reflection, of course.
Q: didn't you say that in the case of using reflection, why not just throw an exception in the constructor?
A: I've really tried this, but it doesn't work. The reflection constructor used in deserialization is not the same as the reflection constructor used in our code. The constructor used in deserialization does not call the constructor in our object. Balabala... I don't know if the interviewer can understand. I feel like I don't understand. )
Q: Oh. OK bar, when can you come to work?
Soon after, I joined the company. When I was chatting with the original interviewer, he inadvertently said to me: when I interviewed you at that time, I was just casually asking about the destruction of the singleton at first. I didn't expect you to blow water on me for 20 minutes. At that time, I thought you were a man of ability.
This is the end of the content of "how to break the singleton mode in Java". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.