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:
  1. Class A implements the serialization interface and defines the static method as A class that cannot be overridden or dynamically bound when usedreadResolveMethod, class B and C both inherit from A, deserialize B, and the deserialization process will call thisinvokeReadResolveMethod through which to make a reflection call ifreadResolveMethod isstaticYou’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 ≦ *)