码迷,mamicode.com
首页 > 其他好文 > 详细

Serializable源码分析

时间:2018-04-29 15:25:41      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:assign   需要   理解   dep   png   oid   section   ==   har   

   通过测试代码分析序列化执行过程,通过本文可以理解writeObject,writeReplace方法的执行顺序,以及序列化执行的具体过程。

public class Author implements Serializable {

  protected int id;
  protected String username;
  protected String password;
  protected String email;
  protected String bio;
  protected Section favouriteSection;

  public Author() {
    this(-1, null, null, null, null, null);
  }

  public Author(Integer id, String username, String password, String email, String bio, Section section) {
    this.id = id;
    this.username = username;
    this.password = password;
    this.email = email;
    this.bio = bio;
    this.favouriteSection = section;
  }

  public Author(int id) {
    this(id, null, null, null, null, null);
  }

  public void setId(int id) {
    this.id = id;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public void setEmail(String email) {
    this.email = email;
  }

  public void setBio(String bio) {
    this.bio = bio;
  }

  public void setFavouriteSection(Section favouriteSection) {
    this.favouriteSection = favouriteSection;
  }

  public int getId() {
    return id;
  }

  public String getUsername() {
    return username;
  }

  public String getPassword() {
    return password;
  }

  public String getEmail() {
    return email;
  }

  public String getBio() {
    return bio;
  }

  public Section getFavouriteSection() {
    return favouriteSection;
  }


  private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    System.out.println("readObject");
    in.defaultReadObject();
  }


  private void writeObject(ObjectOutputStream out) throws  IOException{
    System.out.println("writeObject");
    out.defaultWriteObject();
  }

  Object writeReplace() throws ObjectStreamException{
    System.out.println("writeReplace");
    Author replaced=new Author();
    replaced.setId(123);
    return replaced;
  }

  

@Test
  public void testSeria() throws  Exception{
    Author author=new Author();
    author.setId(456);
    Serializable result= deserialize(serialize((Serializable)author));
    System.out.println(((Author)result).getId());
  }
 protected byte[] serialize(Serializable value) throws Exception {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(value);
    oos.flush();
    oos.close();
    return bos.toByteArray();
  }

  protected Serializable deserialize(byte[] value) throws Exception {
    ByteArrayInputStream bis = new ByteArrayInputStream(value);
    ObjectInputStream ois = new ObjectInputStream(bis);
    Serializable result = (Serializable) ois.readObject();
    ois.close();
    return result;
  }

  

上面的测试代码的结果是什么呢?

writeReplace
writeObject
readObject
123

  通过测试代码可以发现,序列化过程如下:

技术分享图片

 

  相关源码如下

 public final void writeObject(Object obj) throws IOException {
        if (enableOverride) {
            writeObjectOverride(obj);
            return;
        }
        try {
            writeObject0(obj, false);
        } catch (IOException ex) {
            if (depth == 0) {
                writeFatalException(ex);
            }
            throw ex;
        }
    }

  

private void writeObject0(Object obj, boolean unshared)
        throws IOException
    {
       。。。。
            for (;;) {
                // REMIND: skip this check for strings/arrays?
                Class<?> repCl;
                desc = ObjectStreamClass.lookup(cl, true);
                //如果存在writeReplace方法,调用需要序列化对象的writeReplace方法,如果返回对象不为null且writeReplace返回对象和原序列化对象类相同则退出循环
                if (!desc.hasWriteReplaceMethod() ||
                    (obj = desc.invokeWriteReplace(obj)) == null ||
                    (repCl = obj.getClass()) == cl)
                {
                    break;
                }
                cl = repCl;
            }
            
        。。。

            // remaining cases
            if (obj instanceof String) {
                writeString((String) obj, unshared);
            } else if (cl.isArray()) {
                writeArray(obj, desc, unshared);
            } else if (obj instanceof Enum) {
                writeEnum((Enum<?>) obj, desc, unshared);
            } else if (obj instanceof Serializable) { //如果实现了Serializable接口
                writeOrdinaryObject(obj, desc, unshared);
            } else {
                if (extendedDebugInfo) {
                    throw new NotSerializableException(
                        cl.getName() + "\n" + debugInfoStack.toString());
                } else {
                    throw new NotSerializableException(cl.getName());
                }
            }
        } finally {
            depth--;
            bout.setBlockDataMode(oldMode);
        }
    }


     private void writeOrdinaryObject(Object obj,
                                     ObjectStreamClass desc,
                                     boolean unshared)
        throws IOException
    {
    。。。
        try {
            desc.checkSerialize();

            bout.writeByte(TC_OBJECT);
            writeClassDesc(desc, false);
            handles.assign(unshared ? null : obj);
            if (desc.isExternalizable() && !desc.isProxy()) {
                writeExternalData((Externalizable) obj);
            } else {//写序列化数据
                writeSerialData(obj, desc);
            }
        } finally {
            if (extendedDebugInfo) {
                debugInfoStack.pop();
            }
        }
    }


    private void writeSerialData(Object obj, ObjectStreamClass desc)
        throws IOException{
                。。。
                try {
                    curContext = new SerialCallbackContext(obj, slotDesc);
                    bout.setBlockDataMode(true);
                    //调用序列化对象的writeObject方法
                    slotDesc.invokeWriteObject(obj, this);
                    bout.setBlockDataMode(false);
                    bout.writeByte(TC_ENDBLOCKDATA);
                } finally {
                    curContext.setUsed();
                    curContext = oldContext;
                    if (extendedDebugInfo) {
                        debugInfoStack.pop();
                    }
                }
        }
    }

  

 

Serializable源码分析

标签:assign   需要   理解   dep   png   oid   section   ==   har   

原文地址:https://www.cnblogs.com/wei-zw/p/8970950.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!