728x90 JAVA/Effective Java65 Effective Java 보호되어 있는 글 입니다. 2022. 9. 15. item 90. 직렬화된 인스턴스 대신 직렬화 프록시 사용을 검토하라 Serializable은 물론 편리하다. 그러나 버그와 보안 문제가 일어날 가능성이 커질 수 밖에 없다. 이럴 때 '직렬화 프록시 패턴' 을 사용하자. 직렬화 프록시는 readObject 의 방어적 복사보다 강력하다. [ 직렬화 프록시 패턴을 사용하는 방법 ] 바깥 클래스의 논리적 상태를 정밀히 표현하는 중첩 클래스를 설계하고, private static 으로 선언하기 위 '중첩 클래스'가 바로 바깥 클래스의 직렬화 프록시다. 중첩 클래스의 생성자는 단 하나여야 하며, 바깥 클래스를 매개변수로 받는다. 중첩 클래스의 생성자는 인수로 넘어온 인스턴스 데이터를 복사한다. 일관성 검사나 방어적 복사는 필요하지 않다. 직렬화 프록시의 기본 직렬화 형태는 바깥 클래스의 직렬화 형태로 쓰기에 이상적이다. 바깥 클래.. 2022. 9. 15. item 89. 인스턴스 수를 통제해야 한다면 readResolve보다는 열거 타입을 사용하라 item3의 싱글턴 패턴을 보자! 클래스는 바깥에서 생성자를 호출하지 못하게 막는 방식으로 인스턴스가 오직 하나만 만들어짐을 보장한다. public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis() { ... } public void leavingTheBuilding() {...} } 여기서 class 선언부에 implements Serializable을 추가하는 순간 이 클래스는 무슨 짓을 해도 싱글턴이 아니다. 어떤 readObject를 사용하든, 이 클래스가 초기화될 때 만들어진 인스턴스와는 별개인 인스턴스를 반환하게 된다. 이 때 readResolve 기능을 이용하면 readObject가 만들어낸 인스턴스.. 2022. 9. 15. item 88. readObject 메서드는 방어적으로 작성하라 item 50에서는 불변인 날짜 범위 클래스를 만드는데 가변인 Date 필드를 이용했다. 그래서 불변식을 지키고 불변을 유지하기 위해 생성자와 접근자에서 Date 객체를 방어적으로 복사하느라 코드가 상당히 길어졌다. public final class Period { private final Date start; private final Date end; /** * @param start 시작 시각 * @param end 종료 시각; 시작 시각보다 뒤여야 한다. * @throws IllegalArgumentException 시작 시각이 종료 시각보다 늦을 때 발생한다. * @throws NullPointerException start나 end가 null이면 발생한다. */ public Period(Date.. 2022. 9. 13. item 87. 커스텀 직렬화 형태를 고려해보라 개발 일정에 쫓기는 상황에서는 API설계에 노력을 집중하는 편이 낫다. '애자일'하게 다음 릴리스에서 다시 구현하기로 하고, 이번 릴리스에서는 동작만 하게 만들어놓는.. 그런걸 의미한다. 그러나, 클래스가 Serializable을 구현하고 기본 직렬화 형태를 사용한다면, 다음 릴리스 때 버리려 한 현재의 구현에 영원히 발이 묶인다. (ex BigInteger) 따라서, 먼저 고민해보고 괜찮다고 판단될 때만 기본 직렬화 형태를 사용해야 한다. 직렬화 형태는 유연성, 성능, 정확승 측면에서 고민하면 된다. 일반적으로 직접 설계했다고 하더라도 기본 직렬화 형태와 거의 같은 결과가 나올 경우에만 기본 형태를 써야 한다. 객체의 물리적 표현과 논리적 내용이 같다면? 기본 직렬화 형태라도 무방하다. [ 기본 직렬화.. 2022. 9. 13. item 82. 스레드 안정성 수준을 문서화하라 보통, API 문서에 synchronized가 붙은 메서드는 '스레드 안전'하다는 말이 있다. 하지만!!! 이는 언제나 맞는 말은 아니다. JavaDoc이 기본 옵션에서 생성한 API문서에는 synchronized 한정자가 포함되지 않기 때문이다. (메서드에 synchronized를 붙이고 말고는 구현 이슈일 뿐, API에 속하는 것이 아니기 때문이다.) 멀티스레드 환경에서도 API를 안전하게 사용하게 하려면, 클래스가 지원하는 스레드 안전성 수준을 정확히 명시해야 한다. 스레드 안전성 수준 나열 ( 안전성이 좋은 순서) 불변(immutabile) 이 클래스의 인스턴스는 마치 상수와 같아서 외부 동기화도 필요 없다. ex) String, Long, BigInteger 무조건적 스레드 안전(uncondit.. 2022. 9. 1. 이전 1 2 3 4 ··· 11 다음 728x90