`
leonzhx
  • 浏览: 791716 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Item 77: For instance control, prefer enum types to readResolve

阅读更多

1.  The readResolve feature allows you to substitute another instance for the one created by readObject. If the class of an object being deserialized defines a readResolve method with the proper declaration, this method is invoked on the newly created object after it is deserialized. The object reference returned by this method is then returned in place of the newly created object.

 

2.  If you depend on readResolve for instance control, all instance fields with object reference types must be declared transient. Otherwise, it is possible for a determined attacker to secure a reference to the deserialized object before its readResolve method is run. Here’s how it works in more detail. First, write a “stealer” class that has both a readResolve method and an instance field that refers to the serialized singleton in which the stealer “hides.” In the serialization stream, replace the singleton’s nontransient field with an instance of the stealer. You now have a circularity: the singleton contains the stealer and the stealer refers to the singleton. Because the singleton contains the stealer, the stealer’s readResolve method runs first when the singleton is deserialized. As a result, when the stealer’s readResolve method runs, its instance field still refers to the partially deserialized (and as yet unresolved) singleton. The stealer’s readResolve method copies the reference from its instance field into a static field, so that the reference can be accessed after the readResolve method runs. The method then returns a value of the correct type for the field in which it’s hiding. If it didn’t do this, the VM would throw a ClassCastException when the serialization system tried to store the stealer reference into this field:

// Broken singleton - has nontransient object reference field!
public class Elvis implements Serializable {
    public static final Elvis INSTANCE = new Elvis();
    private Elvis() { }
    private String[] favoriteSongs = { "Hound Dog", "Heartbreak Hotel" };
    public void printFavorites() {
        System.out.println(Arrays.toString(favoriteSongs));
    }
    private Object readResolve() throws ObjectStreamException {
        return INSTANCE;
    }
}

public class ElvisStealer implements Serializable {
    static Elvis impersonator;
    private Elvis payload;
    private Object readResolve() {
        // Save a reference to the "unresolved" Elvis instance
        impersonator = payload;
        // Return an object of correct type for favorites field
        return new String[] { "A Fool Such as I" };
    }
    private static final long serialVersionUID = 0;
}

public class ElvisImpersonator {
    // Byte stream could not have come from real Elvis instance!
    private static final byte[] serializedForm = new byte[] {
        (byte)0xac, (byte)0xed, 0x00, 0x05, 0x73, 0x72, 0x00, 0x05,
        0x45, 0x6c, 0x76, 0x69, 0x73, (byte)0x84, (byte)0xe6,
        (byte)0x93, 0x33, (byte)0xc3, (byte)0xf4, (byte)0x8b,
        0x32, 0x02, 0x00, 0x01, 0x4c, 0x00, 0x0d, 0x66, 0x61, 0x76,
        0x6f, 0x72, 0x69, 0x74, 0x65, 0x53, 0x6f, 0x6e, 0x67, 0x73,
        0x74, 0x00, 0x12, 0x4c, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
        0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
        0x3b, 0x78, 0x70, 0x73, 0x72, 0x00, 0x0c, 0x45, 0x6c, 0x76,
        0x69, 0x73, 0x53, 0x74, 0x65, 0x61, 0x6c, 0x65, 0x72, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,
        0x4c, 0x00, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
        0x74, 0x00, 0x07, 0x4c, 0x45, 0x6c, 0x76, 0x69, 0x73, 0x3b,
        0x78, 0x70, 0x71, 0x00, 0x7e, 0x00, 0x02
    };
    public static void main(String[] args) {
        // Initializes ElvisStealer.impersonator and returns
        // the real Elvis (which is Elvis.INSTANCE)
        Elvis elvis = (Elvis) deserialize(serializedForm);
        Elvis impersonator = ElvisStealer.impersonator;
        elvis.printFavorites();
        impersonator.printFavorites();
    }
}

 

3.  If instead you write your serializable instance-controlled class as an enum, you get an ironclad guarantee that there can be no instances besides the declared constants. The JVM makes this guarantee, and you can depend on it. It requires no special care on your part.

 

4.  If you place a readResolve method on a final class, it should be private. If you place a readResolve method on a nonfinal class, you must carefully consider its accessibility. If a readResolve method is protected or public and a subclass does not override it, deserializing a serialized subclass instance will produce a superclass instance, which is likely to cause a ClassCastException.

 

分享到:
评论

相关推荐

    Effective Java 3rd edition(Effective Java第三版英文原版)附第二版

    目录如下: 1 Introduction 2 Creating and Destroying Objects ...Item 89: For instance control, prefer enum types to readResolve Item 90: Consider serialization proxies instead of serialized instances

    tcping查看端口及IP链路情况

    -w 0.5 : for instance, wait 0.5 seconds for a response -d : include date and time on each line -b 1 : enable beeps (1 for on-down, 2 for on-up, 3 for on-change, 4 for always) -r 5 : for instance,...

    Effective C#

    **Item 22: Prefer Defining and Implementing Interfaces to Inheritance** - **Reasons:** Interfaces promote loose coupling and make it easier to swap implementations. - **Implementation:** ```csharp ...

    专享:prefer的用法__(全).pdf

    13. “I would prefer to spend the weekend at home rather than driving all the way to your mother’s.”说话者宁愿在家度过周末,而不愿长途驾车去对方母亲家。 14. “I should prefer beef rather than ...

    新人教九年级英语unit单词讲解PPT课件.pptx

    4. **特定情况**:`prefer to do sth.` 用于强调在特定情境下,更愿意做某事,例如:"I prefer to walk."(我宁愿走路。) 5. **对比形式**:`prefer doing sth. to doing sth.` 这种结构表示在两个动作之间,更...

    leaflet-prefer-canvas:将L_PREFER_CANVAS选项添加到流星的传单地图中

    传单首选画布使用meteorhacks:inject-initial软件包注入L_PREFER_CANVAS = true; 选项,然后加载您喜欢的传单包。 这被添加到您的文档头中: <head> [removed]L_PREFER_CANVAS = true;[removed] ... style...

    Unit6 Good Manners语言点教案示例四 人教版.doc

    - "prefer doing A to doing B"或"prefer to do A rather than do B"都表示宁愿做A而不愿做B。例如:"I prefer working to sitting all day." 这里表达了更倾向于工作的态度。 - "prefer sb. to do sth."表示希望...

    Google C++ Style Guide_英文版.pdf

    - **Integer Types:** Use fixed-size integer types from `<cstdint>` to ensure portability across platforms. - **64-bit Portability:** Ensure your code works correctly on 64-bit systems. - **...

    Google C++ Style Guide(Google C++编程规范)高清PDF

    Therefore, we prefer to minimize includes, particularly includes of header files in other header files. You can significantly minimize the number of header files you need to include in your own ...

    高考英语重点词组固定搭配大全.docx

    此外,还有一些不常接动名词但接不定式的动词,如:aim to do sth., fail to do sth., long to do sth., happen to do sth., hesitate to do sth., struggle to do sth. 二、接不定式作宾补的动词: 1. advise sb....

    Effective C++(第三版)

    prefer pass-by-reference-to-const to pass-by-value. 条款21:必须返回对象时,别妄想返回其reference don't try to return a reference when you must return an object. 条款22:将成员变量声明为private ...

    高中英语 unit 2 english around the world(第5课时)教案 新人教版必修1.doc

    - `prefer to do sth. rather than do sth.` 宁愿做...而不愿做... - `prefer sb. to do sth.` 宁愿某人做... 5. **其他表达**: - **would rather** 的用法: - `would rather (not) do sth.` 宁愿(不)做某事 ...

    高中英语Unit3Traveljournalpart1WarmingupandPre_reading学案无答案新人教版必修1

    - I prefer to read books rather than listen to music. - I prefer doing reading rather than listening to music. - 优缺点分析:思考并列举各种交通方式的利弊,例如环保程度、速度、费用、舒适度等方面。 ...

    【上课用】非谓语考点:动词 固定非谓语to do.docx

    - "prefer to do" 表示更倾向于做某事,而 "prefer doing" 表示平时更喜欢做某事。 题目示例: 3. 题目"If he takes on this work, he will have no choice but ____________an even greater challenge.",这里使用...

    英语词汇固定搭配.doc

    - 主动选择做某事,例如:She chose to study abroad for her master's degree. 8. decide to do sth. - 决定做某事,例如:After much discussion, we decided to invest in the project. 9. demand to do sth. - ...

    安徽省太和县北城中心学校九年级英语全册Unit9IlikemusicthatIcandancetoSectionA1a_2d导学

    3. prefer sth to sth,如:I prefer fish to meat. 或 I prefer reading to playing. 通过以上内容的学习,学生应能理解并运用这些词汇和语法结构,进行关于音乐喜好的交流,同时也能理解和使用定语从句,提升英语...

    介词to的用法归纳.pdf

    * prefer to * compare to * contrast to 这些例句中,to表示比较或对比的意思,强调两者之间的差异或相似性。 五、tҏ 与 及 个 别 的 名 词 构 成 比 较 之 意 在这个用法中,to与及个别的名词构成比较之意。...

    effective c++

    2. **Item 7: Prefer Initialization to Assignment** - **核心观点**:提倡初始化而非赋值,尤其是在构造函数和成员变量的初始化过程中。 - **应用场景**:适用于对象创建时的资源管理,有助于减少内存泄漏和提高...

Global site tag (gtag.js) - Google Analytics