This article is participating in the Java Theme Month – Java Debug Notes Event, see the event link for details
The serialization singleton pattern was mentioned in the previous article, this article will explore its source code, feel it is a very special singleton haha 😄
Serialization singleton pattern implementation ————readResolve source code interpretation
Add the readResolve method to your serializable class to implement the singleton pattern! Why is that? Let’s look at the mystery of the source code!
Serialization can only be performed if serialization interface Serializable is implemented.
The test code
class SingletonTest {*/*** ** Serialization test public method * *** *@param* *className*
**/*
private void testSerializable(String className) {
if (className == null) {
throw new RuntimeException("ClassName cannot be null"); } Class<? > clazz =null;
Object obj = null;
try {
clazz = Class.forName(className);
Method method = clazz.getMethod("getInstance");
obj = method.invoke(null);
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
int lastIndexOf = className.lastIndexOf(".");
String realName = className.substring(lastIndexOf + 1);
String objName = realName + ".obj";
Object s1 = null;
Object s2 = obj;
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(objName);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(s2);
objectOutputStream.flush();
objectOutputStream.close();
FileInputStream fileInputStream = new FileInputStream(objName);
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Object o = objectInputStream.readObject();
s1 = o;
objectInputStream.close();
System.out.println(s1);
System.out.println(s2);
System.out.println(s1 == s2);
} catch(IOException | ClassNotFoundException e) { e.printStackTrace(); }} */*** ** serialization singleton l* **/*
@Test
void testSerializableSingleton(a) {
testSerializable("com.example.demo.singleton.SerializableSingleton"); }}Copy the code
Serialization singleton pattern [Tests]
Comment out the following code first
Perform testSerializableSingleton method, as a result, the diagram below, is not the same object serialization and deserialization, has violated the singleton pattern, that is to say, in this case through the serialization mode can destroy the singleton pattern.
The source code
readObject
Now let’s look at why we’re adding code that’s commented out,
Enter the Object o = objectInputStream. ReadObject ();
Go to the method readObject0 in the red box above, which is the underlying implementation of readObject,
Find the figure below in this method
readOrdinaryObject
Go to the method readOrdinaryObject in the figure above and continue
If obj is not null, it will execute the code shown below
This will check to see if hasReadResolveMethod exists, or if it does, through reflection
InvokeReadResolve creates the object, points obj’s reference address to the currently created object rep, and returns it.
invokeReadResolve
Let’s see what invokeReadResolve does
As you can see from the comment, it will call the readResolve method of the serializable class represented. In idea, click the readResolveMethod method with CTRL + left mouse button and select getInheritableMethod
Knowing that this method is a function with argTypes null and return type Object, what is its modifier?
The method returns null if it is static or ABSTRACT,
An abstract method doesn’t have a method body, it needs a non-abstract subclass to implement it, so it returns NULL,
Static returns null. Hope to see the great gods of this blog to help answer questions!! 🐖 thank you!!
I’ve been thinking about this for a long time but I can’t figure out the answer. Until I revisit its method name, getInheritableMethod: Get methods that can inherit 🙃
Guess:
- Class A implements the serialization interface and defines the static method as A class that cannot be overridden or dynamically bound when used
readResolve
Method, class B and C both inherit from A, deserialize B, and the deserialization process will call thisinvokeReadResolve
Method through which to make a reflection call ifreadResolve
Method isstatic
You’re not going to find the method. 🐷
To test the guess, do a simple inheritance test! As shown in figure:
The output result is shown as follows:
B) getDeclaredMethods: getDeclaredMethods: getDeclaredMethods: getDeclaredMethods:
And the source (the previous picture 😄) is through the getDeclaredMethod method to obtain! This method can only fetch methods defined by the class itself.
Other access modifiers will return this method only if they match the corresponding permission.
The following table:
The modifier | The current class | With the package | A subclass | Different packages |
---|---|---|---|---|
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
default | Y | Y | N | N |
private | Y | N | N | N |
I am 4ye and we will see you next time ヾ( ̄▽ ̄)Bye Bye
Welcome attention, make a friend!! (•̀ ω •́)y
Hey hey like to support below 😋
Let’s start this unexpected meeting! ~
Welcome to leave a message! Thanks for your support! O (≧ ヾ del ≦ *)