• Effective Java 76 Write readObject methods defensively


    Principle

    1. readObject method is effectively another public constructor, and it demands all of the same care as any other constructor. Just as a constructor must check its arguments for validity (Item 38) and make defensive copies of parameters where appropriate (Item 39), so must a readObject method.
    2. When an object is deserialized, it is critical to defensively copy any field containing an object reference that a client must not possess.
    3. Do not use the writeUnshared and readUnshared methods.
    4. If it is not comfortable adding a public constructor that took as parameters the values for each nontransient field in the object and stored the values in the fields with no validation, you must provide a readObject method, and it must perform all the validity checking and defensive copying that would be required of a constructor. Alternatively, you can use the serialization proxy pattern(Item 78).

    /**

    * @author Kaibo Hao Immutable class that uses defensive copying

    */

    public final class Period implements Serializable {

    private Date start;

    private Date end;

       

    /**

    * @param start

    * the beginning of the period

    * @param end

    * the end of the period; must not precede start

    * @throws IllegalArgumentException

    * if start is after end

    * @throws NullPointerException

    * if start or end is null

    */

    public Period(Date start, Date end) {

    this.start = new Date(start.getTime());

    this.end = new Date(end.getTime());

    if (this.start.compareTo(this.end) > 0)

    throw new IllegalArgumentException(start + " after " + end);

    }

       

    public Date start() {

    return new Date(start.getTime());

    }

       

    public Date end() {

    return new Date(end.getTime());

    }

       

    public String toString() {

    return start + " - " + end;

    }

       

    // Remainder omitted

       

    // readObject method with defensive copying and validity checking

    private void readObject(ObjectInputStream s) throws IOException,

    ClassNotFoundException {

    s.defaultReadObject();

    // Defensively copy our mutable components

    start = new Date(start.getTime());

    end = new Date(end.getTime());

    // Check that our invariants are satisfied

    if (start.compareTo(end) > 0)

    throw new InvalidObjectException(start + " after " + end);

    }

    }  

    Guidelines for writing a bulletproof readObject method

    1. For classes with object reference fields that must remain private, defensively copy each object in such a field. Mutable components of immutable classes fall into this category.
    2. Check any invariants and throw an InvalidObjectException if a check fails. The checks should follow any defensive copying.
    3. If an entire object graph must be validated after it is deserialized, use the ObjectInputValidation interface [JavaSE6, Serialization].
    4. Do not invoke any overridable methods in the class, directly or indirectly.  

    Summary

    Anytime you write a readObject method, adopt the mind-set that you are writing a public constructor that must produce a valid instance regardless of what byte stream it is given. Do not assume that the byte stream represents an actual serialized instance.

  • 相关阅读:
    log记录日志使用说明
    浅谈WebService开发三(动态调用WebService)转
    浅谈WebService开发二(同步与异步调用)转
    浅谈WebService开发(一)转
    Log4net使用(二)
    Log4net使用(一)
    创建DSN
    Oracle的substr函数简单用法(转)
    医院里的CR、DR、CT、磁共振、B超都是什么?
    lambda表达式(2)
  • 原文地址:https://www.cnblogs.com/haokaibo/p/write-readObject-methods-defensively.html
Copyright © 2020-2023  润新知