목록책 정리/이펙티브 자바 3 (36)
초보개발자 긍.응.성

객체 직렬화란 자바가 객체를 바이트 스트림으로 인코딩하고(직렬화) 그 바이트 스트림으로부터 다시 객체를 재구성하는(역직렬화) 메커니즘이다. 직렬화된 객체는 다른 VM에 전송하거나 디스크에 저장한 후 나중에 역직렬화할 수 있다. 직렬화가 품고 있는 위험과 그 위험을 최소화하는 방법을 배워보자. 자바 직렬화의 대안을 찾으라 직렬화는 위험하니 피해야 한다. ObjectInputStream의 readObject는 객체 그래프가 역직렬화된다. 역직렬화를 통하면 클래스 패스 안의 모든 타입의 객체를 만들어 그 타입들 안의 모든 코드를 수행할 수 있다. 즉, 그 타입들의 코드 전체가 공격 범위에 들어간다는 뜻이다. 직렬화 위험을 회피하는 가장 좋은 방법은 아무것도 역질렬화 하지 않는 것이다. 새로운 시스템에서 자바 ..

스레드는 여러 활동을 동시에 수행할 수 있게 해준다. 하지만 동시성 프로그래밍은 단일 스레드 프로그래밍보다 어렵다. 이번 장에는 동시성 프로그램을 명확하고 정확하게 만들고 잘 문서화하는 방법을 배워보자. 공유 중인 가변 데이터는 동기화해 사용하라 synchronized 키워드는 해당 메서드나 블록을 한 번에 한 스레드씩 수행하도록 보장한다. 동기화는 배타적 실행뿐 아니라 스레드 사이의 안정적인 통신에 꼭 필요하다. long, double, boolean 필드를 읽고 쓰는 작업은 원자적이다. 하지만 공유 중인 가변 데이터가 비록 원자적으로 읽고 쓸 수 있을지라도 동기화하지 않으면 메인 스레드가 수정한 값을 백그라운드 스레드가 언제쯤에나 보게 될지 보증할 수 없다. public class StopThread..

예외를 제대로 활용한다면 프로그램의 가독성, 신뢰성, 유지보수성이 높아지지만, 잘못 사용하면 반대의 효과만 나타난다. 예외를 효과적으로 활용하는 지침들에 대해 배워보자. 예외는 진짜 예외 상황에만 사용하라 예외는 그 이름이 말해주듯 오직 예외 상황에서만 써야 한다. 절대로 일상적인 제어 흐름용으로 쓰여선 안 된다. 잘 설계된 API라면 클라이언트가 정상적인 제어 흐름에서 예외를 사용할 일이 없게 해야 한다. 특정 상태에서만 호출할 수 있는 '상태 의존적' 메서드를 제공하는 클래스는 '상태 검사' 메서드도 함께 제공해야 한다. 예시로 Iterator 인터페이스의 hasNext와 next메서드가 각각 상태 검사와 상태 의존적 메서드이다. for-each도 내부적으로 hasNext를 사용한다) 상태 검사 메서..

지역변수의 범위를 최소화하라 지역변수는 가장 처음 쓰일 때 선언하고, 선언과 동시에 초기화하도록 하자. 변수를 초기화하는 표현식에서 검사 예외를 던질 가능성이 있다면 try 블록 안에서 초기화하라. 메서드를 작게 유지하고 한 가지 기능에 집중하게 하라. 전통적인 for 문 보다는 for-each 문을 사용하라 전통적인 for 문은 반복자와 인덱스 변수가 여러 번 등장된다. 향상된 for-each문을 반복자와 인덱스 변수를 사용하지 않기에 코드가 더 깔끔해지고 오류가 날 일도 없다. for-each문은 배열은 물론 Iterable 인터페이스를 구현한 객체라면 무엇이든 순회할 수 있다. 아래와 같은 상황이 아니면 for-each문을 사용하자. 파괴적인 필터링 (destructive filtering) - 컬..

매개변수가 유효한지 검사하라 메서드와 생성자 대부분은 입력 매개변수의 값이 특정 조건을 만족하기를 바란다. 메서드 몸체가 실행되기 전에 매개변수를 확인한다면 잘못된 값이 넘어왔을 때 즉각적이고 깔끔한 방식으로 예외를 던질 수 있다. public과 protected 메서드는 매개변수 값이 잘못됐을 때 던지는 예외를 문서화해야 한다. 자바 7에 추가된 java.utils.Objects.requireNonNull 메서드는 유연하고 사용하기도 편하니, 더 이상 null 검사를 수동으로 하지 않아도 된다. this.strategy = Objects.requireNonNull(strategy, "전략"); 단언문(assert)를 사용해 매개변수 유효성을 검증할 수 있다. private static void sort..

익명 클래스보다는 람다를 사용하라 익명 클래스 방식은 너무 코드가 길다. 단 하나의 추상 메서드를 갖는 함수형 인터페이스는 람다식으로 표현하자. 람다식의 경우 타입을 명시해야 코드가 더 명확할 때만 제외하고는, 람다의 모든 매개변수 타입은 생략하자. 익명 클래스는 함수형 인터페이스가 아닌 타입의 인스턴스를 만들 때만 사용하라 대신 람다는 이름이 없고 문서화도 못한다. 따라서 코드 자체로 동작이 명확히 설명되지 않거나 코드 줄 수가 많아지면 람다를 쓰지 말아야 한다. 람다보다는 메서드 참조를 사용하라 람다가 익명 클래스보다 나은 점 중에서 가장 큰 특징은 간결함이다. 하지만 더 간결한 방법은 메서드 참조이다. 미리 정의된 메서드 참조를 사용해도 되고, 람다로 작성할 코드를 메서드에 담은 다음 람다 대신 그..