We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Originally posted by bunsung92 April 10, 2023
readResolve()
transient
인스턴스 수를 통제하는 기법은 바로 싱글턴이다. 그리고 직렬화와 싱글턴은 상성이 맞지 않다.
싱글턴
직렬화
바로 implement Serializable 을 추가하는 순간 싱글턴이 아니게 되기 때문이다. 기본 직렬화를 쓰지 않더라도 (아이템 87) 명시적인 readObject() (아이템88) 를 제공하더라도 소용없다.
implement Serializable
readObject()
어떤 readObject()를 사용하든 이 클래스가 초기화될 때 만들어진 인스턴스와는 별개의 인스턴스를 반환하기 때문이다.
readObject() 가 별개의 인스턴스를 반환하기만을 마냥 기다릴 수 없다. readResolve()를 가용하여 필연적으로 원본의 Instance를 반환하게 지시할 수 있다.
public class Foo { private static final Foo INSTANCE = new Foo(); private Foo() { } public static Foo getINSTANCE() { return INSTANCE; } // readResolve 메서드를 정의한다. private Object readResolve() { // 싱글턴을 보장하기 위함! return INSTANCE; } }
이때 만약에 싱글턴 클래스의 필드가 존재한다면, 해당 필드는 반드시 모두다 transient 키워드를 추가해야한다. readResolve()가 수행되기전에 역 직렬화된 객체의 참조를 공격할 여지가 남는다.
즉 구현 여부를 판단하여 readResolve() 를 호출하기 전에 어떤 동작을 해버리면 막기 어려워진단 말임!
readResolve()와 도둑 클래스
직렬화 가능한 인스턴스 통제 클래스를 열거 타입을 이용해 구현하면, 선언한 상수 외의 다른 객체가 존재하지 않는다는것을 자바가 보증한다.
자바
native 코드
readResolve()는 완전히 쓸모 없어진것이 아니다.
하위 클래스에서 readResolve()를 재정의 하지 않고 형 변환을 통해 해당 직렬화를 이용 했다면, ClassCastException 이 발생한다.
ClassCastException
정리하자면 반드시 하위 클래스에서는 readResolve()를 정의해야 한다는 것이다!
1. readResolve() 2. 열거타입
2023-04-23 (일)
참조 자료 https://madplay.github.io/post/what-is-readresolve-method-and-writereplace-method https://stackoverflow.com/questions/1168348/java-serialization-readobject-vs-readresolve https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A7%81%EB%A0%AC%ED%99%94Serializable-%EC%99%84%EB%B2%BD-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0
참조 자료
https://madplay.github.io/post/what-is-readresolve-method-and-writereplace-method https://stackoverflow.com/questions/1168348/java-serialization-readobject-vs-readresolve https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A7%81%EB%A0%AC%ED%99%94Serializable-%EC%99%84%EB%B2%BD-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0
The text was updated successfully, but these errors were encountered:
Irisation23
No branches or pull requests
Discussed in https://github.com/orgs/Study-2-Effective-Java/discussions/204
Originally posted by bunsung92 April 10, 2023
0. TL;DR 📚
readResolve()
작성하고, 클래스의 모든 참조 타입 인스턴스 필드를transient
키워드를 이용하자.1. 인스턴스 수의 통제
인스턴스 수를 통제하는 기법은 바로
싱글턴
이다.그리고
직렬화
와싱글턴
은 상성이 맞지 않다.바로
implement Serializable
을 추가하는 순간 싱글턴이 아니게 되기 때문이다.기본 직렬화를 쓰지 않더라도 (아이템 87)
명시적인
readObject()
(아이템88) 를 제공하더라도 소용없다.어떤
readObject()
를 사용하든 이 클래스가 초기화될 때 만들어진 인스턴스와는 별개의 인스턴스를 반환하기 때문이다.2. readResolve()
readObject()
가 별개의 인스턴스를 반환하기만을 마냥 기다릴 수 없다.readResolve()
를 가용하여 필연적으로 원본의 Instance를 반환하게 지시할 수 있다.이때 만약에 싱글턴 클래스의 필드가 존재한다면, 해당 필드는 반드시 모두다
transient
키워드를 추가해야한다.readResolve()
가 수행되기전에 역 직렬화된 객체의 참조를 공격할 여지가 남는다.2.1 deep To
readResolve()
readResolve()와 도둑 클래스
3. 싱글턴과 열거 타입
직렬화 가능한 인스턴스 통제 클래스를 열거 타입을 이용해 구현하면, 선언한 상수 외의 다른 객체가 존재하지 않는다는것을
자바
가 보증한다.native 코드
까지 조작한다면 이는 완전하지 않을 수 있다.readResolve()는 완전히 쓸모 없어진것이 아니다.
3.1 readResolve()와 접근제어자
정리하자면 반드시 하위 클래스에서는 readResolve()를 정의해야 한다는 것이다!
4. 핵심 정리 📚
readResolve()
보다 적다.5. 회고 🧹
2023-04-23 (일)
The text was updated successfully, but these errors were encountered: