[아이템 50]에서 불변인 날짜 범위 클래스를 만드는 데 가변인 Data필드의 불변을 유지하기 위해 생성자와 접근자에서 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..
고민 후 괜찮다고 판단할 때만 기본 직렬화 형태 사용하기 유연성 , 성능, 정확성 측면에서 신중히 고민 후 합당할 때만 사용 이상적인 직렬화 상태 : 객체의 물리적 표현(코드로 어떻게 구현했는지)과 논리적 내용(실제로 의미하는 것)이 같다면 기본 직렬화 형태여도 무방함 //기본 직렬화 형태에 적합 public class Name implements Serializable { private final Stirng lastName; private final String firstName; private final String middleName; } 기본 직렬화 형태가 적합하더라도 불변식 보장과 보안을 위해 readObject 메서드를 제공해야 할 때가 많음. 위의 예시에서 lastName, firstNam..
Serializable Serializable 인터페이스의 구현 클래스는 인스턴스를 직렬화할 수 있다. Serializable 구현은 아주 값비싼 일 Serializable 구현 후 릴리스한 뒤에는 수정이 어려움 직렬화 형태도 하나의 공개 API가 되어 영원히 지원해야함 자바의 기본 직렬화 형태에서는 클래스의 private, protected 필드들도 API로 공개되어 캡슐화가 깨짐 뒤늦게 클래스 내부 구현을 손보면 원래의 직렬화 형태와 달라지게되어 안됨 직렬화 가능 클래스를 만들고자 한다면 고품질의 직렬화 형태도 주의해서 함께 설계해야함 [아이템 87,90] 모든 직렬화된 클래스는 고유 식별 번호를 부여받고 (serialVersionUID라는 static final long 필드), 이 번호를 명시하지..
직렬화 java.io.Serializable 인터페이스를 상속받은 객체를 외부의 자바 시스템에서도 사용할 수 있도록 byte 형태로 데이터를 변환하는 기술 직렬화의 문제는 공격범위가 너무 넓고 지속적으로 더 넓어져 방어하기 어렵다는 점 (객체를 역직렬화할 수 있어서 공격에 위험함) 역직렬화 : 직렬화와 반대로 byte로 변환된 데이터를 객체로 변환하는 기술 자바의 표준 라이브러리, 서드파티 라이브러리, 애플리케이션 자신의 클래스들 모두 공격범위에 포함된다. 가젯 보안 전문가들이 찾은 자바 라이브러리와 서드파티 라이브러리에서 직렬화 가능 타입들을 연구하여 역직렬화 과정에서 호출되어 잠재적으로 위험한 동작을 수행하는 메서드들 여러 가젯을 사용하여 네이티브 코드를 마음대로 실행하는 공격을 하기도 함 → 아주 ..
스레드 스케줄러 여러 스레드가 실행중이면 운영체제의 스레드 스케줄러가 어떤 스레드를 얼마나 오래 실행할지 정한다. 운영체제는 모두 공정하게 수행하지만 구체적인 운영정책은 운영체제마다 다를 수 있다. 이 정책에 좌지우지 되지 않아야 좋은 프로그램이다. 정확성이나 성능이 스레드 스케줄러에 따라 달라지는 프로그램은 다른 플랫폼에 이식하기 어렵다. 실행 가능한 스레드 수를 적게 유지하는 방법 실행 가능한 스레드의 평균적인 수를 프로세서 수보다 지나치게 많아지지 않도록 해야한다. 1) 스레드는 당장 처리해야할 작업이 없다면 실행돼서는 안된다. 스레드 풀 크기를 적절히 설정하고 작업은 짧게 유지해야하나, 너무 짧으면 오히려 분배 부담이 늘어나 성능이 떨어진다. 바쁜 대기(busy waiting) 상태가 되면 안된다..
지연 초기화 (lazy initialization) 필드 초기화 시점을 그 값이 처음 필요할 때 까지 늦추는 기법 정적 필드와 인스턴스 필드에 모두 사용 가능 주로 최적화 용도지만, 클래스와 인스턴스 초기화 때 발생하는 위험한 순환 문제를 해결하는 효과도 있음 지연 초기화는 필요할 때까지는 하지 말라 클래스나 인스턴스 생성 시 초기화 비용은 줄지만, 지연 초기화하는 필드에 접근하는 비용은 커짐 지연 초기화하려는 필드들 중 초기화가 이루어지는 비율에 따라, 실제 초기화 비용에 따라, 초기화 된 각 필드를 얼마나 빈번히 호출하느냐에 따라 지연 초기화가 성능이 느려지게 할 수도 있음 지연 초기화가 필요할 때 해당 클래스의 인스턴스 중 그 필드를 사용하는 인스턴스의 비율 < 그 필드 초기화 비용 일 때 정말 그..
스레드 안전성 한 메서드를 여러 스레드가 동시에 호출할 때 그 메서드가 어떻게 동작하는 지는 해당 클래스와 사용자와의 중요한 계약이다. 메서드 선언에 synchronized 한정자를 선언할지는 구현 이슈일 뿐 API에 속하지 않음 그래서 그것만으로 스레드 안전하다고는 할 수 없음 멀티스레드 환경에서도 API를 안전하게 사용하게 하려면 클래스가 지원하는 스레드 안전성 수준을 정확히 명시해야함 스레드 안전성이 높은 순 불변(immutable) : 이 클래스의 인스턴스는 마치 상수같아서 외부 동기화도 필요 없음. ex) String, Long, BigInteger [아이템 7] 무조건적 스레드 안전 : 이 클래스의 인스턴스는 수정될 수 있으나 내부에서 잘 동기화하여 외부 동기화 없이 동시에 사용해도 안전하다...
동시성 유틸리티 자바5에 도입된 고수준의 동시성 유틸리티 덕분에 자바의 wait와 notify [아이템 50] 를 사용해야 할 이유가 줄었다. wait와 notify는 올바르게 사용하기 까다로우니 고수준 동시성 유틸리티를 사용하자. java.util.concurrent의 고수준 유틸리티의 범주 : 실행자 프레임워크 [아이템 80], 동시성 컬렉션(concurrent collection), 동기화 장치(sychronized) 동시성 컬렉션 표준 컬렉션 인터페이스에 동시성을 가미해 구현한 고성능 컬렉션 높은 동시성을 위해 동기화를 각자 내부에서 수행 [아이템 79] 동시성 컬렉션에서 동시성을 무력화하는 것은 불가능, 외부에서 락을 추가로 사용하면 오히려 속도가 느려짐 동시성 무력화가 불가능하므로 여러 메서드..