클라이언트가 클래스의 인스턴스를 얻는 전통적인 수단은 pulic 생성자이다. 하지만 클래스의 인스턴스를 얻는 다른 방법이 있는데, 정적 팩터리 메서드 라고 하는 방법이 있다. 다음 코드는 boolean의 박싱클래스(Wrapper class)인 Boolean에서 발췌한
객체 생성 방식 중 하나인 생성자(constructor) 대신 정적 팩터리 메서드(static factory method)를 고려해야 하는 이유에 대해 쉽고 자세하게 설명드리겠습니다. 이 개념은 Joshua Bloch의 저서 Effective Java에서 자세히 다루어
생성자에 매개변수가 많다면 빌더를 고려하라일단 빌더패턴 전에빌더 패턴을 사용하기 전, 많은 선택적 매개변수를 처리하기 위해 아래 두 가지 패턴이 사용되었다.점층적 생성자 패턴정적 팩터리와 생성자에는 똑같은 제약이 하나 있다.선택적 매개변수가 많을 때 적절히 대응하기 어

private 생성자나 열거 타입으로 싱글턴임을 보증하라싱글톤이란?인스턴스를 오직 하나만 생성할 수 있는 클래스무상태 객체 or 설계상 유일해야 하는 시스템 컴포넌트문제점클래스를 싱글톤으로 만들면, 이를 사용하는 클라이언트를 테스트하기가 어려워질 수 있다고 합니다. 타
특정 기능들을 제공하는 클래스들 ex) Math 처럼 공통적으로 사용되는 클래스 또는 상수값을 모아두는 클래스 등등은 객체화를 위해 만든것이 아니므로상속과 인스턴스화를 막는것이 좋다. 만약 클래스 자체에 생성자가 없는경우 jdk 는 자동으로 NoArgsConstruct
참고https://github.com/SeolYoungKim/effective_java_study

몇몇 이유를 빼면 객체 하나를 재사용하는 편이 보통의 경우 객체 하나를 재사용하는 편이 퍼포먼스적으로 이득이다.또, 본인은 그걸 의도하지 않았더라도 새로운 객체를 생성하는 경우를 주의하라.몇몇 이유 : 보안, thread safe, stream책에서 여러 케이스를 지적

GC는 참조하지 않는 객체를 알아서 회수해준다.하지만 그렇다고 해서 메모리 관리에 신경을 안 쓸 수는 없다.사용은 안하지만 참조를 해제하지 않는 코드는 주의해야 한다.아래는 메모리 누수가 일어나는 스택 예제다.문제가 없어 보이지만, pop()함수는 numbers에서 들
자바는 두 가지 객체 소멸자를 제공finalizer는 예측할 수 없고, 상황에 따라 위험할 수 있다기본적으로 쓰지말아야 한다. 자바9 부터는 deprecated대안으로 cleaner가 생겼지만 이것도 쓰면 안됨이 책에서는 try-with-resource와 try-fin

자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야 하는 리소스가 많습니다.InputStreamOutputStreamjava.sql.Connectionetc자원을 닫는 것은 사용자가 놓치기 쉬운 부분입니다. 사실 저도 BufferedReader를 사용하고 닫지
각 인스턴스가 본질적으로 고유하다. Person 객체는 이름이 같아도 본질적으로 고유해서 객체 참조 비교를 사용하는게 옳다.논리적 동치성을 검사할 필요가 없다. 위는 논리적 동치성을 검사해야 하는 예제로 PersonName 객체는 이름이 같으면 논리적으로 같다.
equals를 재정의한 클래스 모두에서 hashCode도 재정의해야 한다. 그렇지 않으면 프로그램이 제대로 동작하지 않을 것이다. 재정의한 hashCode는 Object의 API 문서에 기술된 일반 규약을 따라야 하며, 서로 다른 인스턴스라면 되도록 해시코드로 서로 다
구체 클래스를 작성할땐 toString() 메소드를 구현하라. 객체가 가진 '주요'정보를 명확하고 (사람이) 읽기 좋게 반환해야한다.'읽기좋다' 라는 뜻은 반드시 포멧을 지정해야 한다는 뜻이 아니다.여러 클래스를 작성하며 디버깅을 해야할일이 많았을 것이다.실제로 위와
기존 인터페이스는 해당 인터페이스에 정의된 메서드를 구현 클래스에서 구현해주는 방식으로 진행되지만,Clone 의 경우 Object 객체를 Native로 돌려야 되기 때문에 메서드 자체는 Object 에 표시되며 인터페이스 Cloneable 을 통해 해당 클래스의 객체가
순서가 있는 클래스를 작성한다면, Comparable 인터페이스를 구현하는 것이 좋다.compareTo 메서드를 구현할 때는 박싱 클래스에서 제공하는 compare()를 적극 활용하자.Comparable 인터페이스는 객체를 정렬하는데 사용되는 메서드인 compareTo
클래스 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 얼마나 잘 숨겼는가.오직 API를 통해서만 다른 컴포넌트와 소통하며, 서로의 내부 동작 방식에는 전혀 개의치 않는다.정보 은닉, 캡슐화 라고 한다.시스템 개발 속도를 높인다. \- 여러 컴포넌트를 병렬로 개발할

아래와 같은 클래스는 "인스턴스 필드를 모아놓는 역할" 외에는 아무것도 하지 않는 "퇴보한 클래스"입니다.이와 같은 클래스는 데이터 필드에 직접 접근할 수 있습니다. 따라서, 캡슐화의 이점을 제공하지 못합니다.API를 수정하지 않고는 내부 표현을 바꿀 수 없습니다.
불변 객체를 사용해라.불변 객체가 연산이 될때마다 새로운 객체를 생성하므로 이부분만 주의하면 될듯.자바 표준 라이브러리의 String, Integer, Long 등의 타입은 불변 타입이다.불변 객체는 단순하며, 유지보수하기에 가변 객체보다 쉽다.여기서 잠깐 불변 객체에
여기서 단 하나 래퍼클래스는 단점이 거의 없다. 단 하나, 래퍼클래스가 콜백 프레임워크와는 어울리지 않는다는 점만 주의 하면 된다.라고 했다.애초에 컴포지션과 상속은 쓰임새가 다르다고 생각하지만.. 아무튼 예를들어 작성된 프로젝트입니다.AppMain.java AppMa
참고https://github.com/SeolYoungKim/effective_java_study
정리하자면 일반적으로 다중 구현용 타입으로는 인터페이스가 가장 적절하며 재사용성 측면이나 유연성 측면 그리고 다형성 측면에서 인터페이스를 우선하는 것이 옳다.자바에는 인터페이스와 추상 클래스를 제공한다.자바 8 부터는 인터페이스에 default method를 제공하게

https://www.acmicpc.net/problem/1205이번 문제는 디제이맥스(DJMAX) 게임의 랭킹 리스트에 새로운 점수를 추가할 때, 그 점수가 랭킹 리스트에서 몇 등인지 결정하는 문제입니다. 주어진 랭킹 리스트는 비오름차순(내림차순으로 정렬)으
기존 인터페이스에 디폴트 메서드 구현을 추가하는 것은 위험한 일입니다.디폴트 메서드는 구현 클래스에 대해 아무것도 모른 채, 합의 없이 무작정 "삽입"될 뿐입니다.디폴트 메서드는 기존 구현체에 런타임에 어떠한 오류를 발생시킬 가능성이 있습니다. (런타임 에러가 될 수도
인터페이스는 자신을 구현한 클래스의 인스턴스를 참조할 수 있는 타입 역할만 하는데, 오직 이 용도로만 사용해야 한다.상수 인터페이스라는 안티패턴이 있는데, 절대 사용하지말라고 한다.상수 인터페이스 안티패턴은 인터페이스를 잘못 사용한 예이다.클래스 내부에서 사용하는 상수
내부 멤버 객체를 태그삼아 여러개의 의미를 가지는 클래스를 생성하지마라.비효율적이며, 확장하기 쉽지 않으며 런타임 오류를 내기 쉽다. 일단 '태그달린 클래스' 라는 말을 정의 하자.책의 코드를 모두 옮기지 않고, 단어 정의를 위해 일부만 발췌하였다.내부 멤버(태그)에
맴버 클래스는 중첩 클래스로 정적 맴버 클래스와 비정적 맴버 클래스로 나뉜다.정적 맴버 클래스는 다른 클래스 안에 선언되는데,바깥 클래스의 private 맴버에도 접근할 수 있다.정적 맴버 클래스는 다른 정적 맴버와 같은 규칙을 적용한다.예를 들어 private으로 선
이 주제는 자바(Java) 프로그래밍에서 중요한 설계 결정 중 하나로, 클래스의 구조와 동작에 큰 영향을 미칠 수 있습니다. 아래에서 맴버 클래스의 개념, static 맴버 클래스와 non-static 맴버 클래스의 차이점, 각각의 장단점, 그리고 언제 static으로
톱 레벨 클래스란 '파일' 내에서 중첩되지 않은 클래스를 의미하며 위의 코드의 경우 Foo 는 톱 레벨 클래스로 볼수있다.이제 톱 레벨 클래스의 활용 시 문제가 생길만한 부분을 살펴보자위와 같이 단순 test1.NAME+ test2.NAME 의 호출을 위한 Foo cl
제네릭 클래스 : 선언에 타입 매개변수가 쓰인 클래스제네릭 인터페이스 : 선언에 타입 매개변수가 쓰인 인터페이스제네릭 타입 : 제네릭 클래스와 제네릭 인터페이스를 통틀어 부르는 용어일련의 매개변수화 타입(Parameterized type)을 정의한다.제네릭 타입을 하나
제네릭을 사용하면 비검사 경고를 처리해야 할 때가 있다.보통의 경우, 컴파일러의 경고를 보고 쉽게 해결할 수 있다.위와 같은 코드는 컴파일러가 경고를 내보낸다.(로 타입 HastSet을 사용했다는 경고)자바 7부터 타입 매개변수를 명시하지 않아도 <>를 사용해서
배열보다는 되도록이면 리스트를 사용하라 되도록이면 리스트를 사용하라.리스트는 제네릭타입이 적용되어 있으므로 문제가 있는 코드는 컴파일조차 되지 않는다.배열과 리스트는 비슷해보이지만 차이가 있다. 배열은 공변이지만 리스트는 불공변이다. 공변? 불공변? 배열은 공변이
위 처럼 모든 객체의 상위객체인 Object 형으로 코딩을 하는경우타입관리의 엄밀함이 떨어지게 된다 .따라서 아래와 같이 제네릭을 사용해주면 타입관리의 장점을 취할수 있다.다만 위처럼 변환시 기존 new Object\[] 같은 방식으로 생성된 부분들은 오류가 날수 있는
클래스와 마찬가지로, 메서드도 제네릭으로 만들 수 있다.매개변수화 타입을 받는 정적 유틸리티 메서드는 보통 제네릭이다.매개변수화 타입을 받는 정적 유틸리티 메서드는 보통 제네릭이다.Collections의 binarySearch, sort 등 알고리즘 메서드는 모두 제네
List<String> 는 List<Object> 가 하는 일을 제대로 수행하지 못하니 리스코프 치환 원칙에 어긋난다.Stack.javaMain.java위의 코드와 같이 Stack<Number>로 클래스를 선언한 뒤, Number의 하위타입인 Integ
가변인수를 사용하면 인수를 담기 위한 배열을 하나 만들어서 사용한다.가변인수를 출력하는 예제를 보자.결과는 스트링 배열(\[Ljava.lang.String;@531be3c5)이 나온다.위 함수는 호출하면 String s = strings\[0].get(0)에서 런타임
제네릭은 하나의 컨테이너에서 매개변수화할 수 있는 타입의 수가 제한된다고 합니다.예를 들어, Set<E>에는 원소의 타입을 뜻하는 단 하나의 타입 매개변수만 있으면 되며, Map<K,V> 에는 키와 값을 뜻하는 2개만 필요합니다.컨테이너 대신 "키"를 매개변
열거 타입 상수는 순서가 적용되는데, 선언 순서대로 "순서 값"을 갖게 됩니다.해당 순서 값은 Enum에서 기본으로 제공하는 ordinal()메서드를 통해 받아올 수 있습니다. (이는 0부터 할당됩니다.)예를 들어, 해당 순서 값은 다음과 같이 사용될 수 있습니다. 아
enum값으로 원소를 그룹화 시켜야 할 필요가 있을때,enum의 Ordinal 에 의존하지 말고, enum 값 자체를 이용하여 그루핑하라.item 34, 35에 이어 Ordinal값을 이용하여 개념적인 프로그램을 짜기보다는자바가 지원하는 기능을 이용하여 명시적인 프로그
열거 타입은 확장(extends)할 수 없다.다만, interface를 구현(implements)할 수는 있다. (확장을 흉내낸다고 표현함.)간단한 계산기의 연산 기능을 구현할 때API가 제공하는 기본 연산 외에, 사용자 확장 연산을 추가할 수 있도록 열어줘야 할 때책
전통적으로 도구나 프레임워크에서 다뤄야 하는 프로그램 요소에는 명명 패턴이 사용되어 왔다.예를 들면 JUnit은 버전 3까지 테스트 메서드 명에 test를 붙여야 했다.이런 방식의 테스트 단점1\. 오타가 나면 안된다. testA를 tsetA로 잘못지으면 테스트가
자바가 기본으로 제공하는 애너테이션 중에서 보통 가장 중요한 어노테이션으로 @Override 을 꼽을 수 있다.이 어노테이션을 일관되게 사용하면 여러 가지 악명 높은 버그들을 예방해준다.Object의 equals를 override를 하려면 매개변수가 Object여야 하
아무 메서드도 담고 있지 않고, 자신을 구현하는 클래스가 특정 속성을 가짐을 표시 해주는 인터페이스를 마커 인터페이스라 합니다.대표적으로는 Serializeable 인터페이스를 예로 들 수 있습니다.Serializeable은 자신을 구현한 클래스의 인스턴스는 직렬화할
익명 클래스는 구구절절히 작성되어 가독성이 좋지 못하므로 될수있으면 람다로 작성하라.일회성으로 사용될 객체를 만들기 위해서 익명 클래스를 만들어 제공하곤 한다.이름에서부터 알수있듯 이름을 지정할정도로 중요한것이 아니고, 재사용성이 없고, class 문서 파일을 만들 필
메서드 참조는 람다의 간단명료한 대안이 될 수 있다. 메서드 참조 쪽이 짧고 명확하다면 메서드 참조를 쓰고, 그렇지 않을 때만 람다를 사용하라.람다가 익명 클래스보다 나은 점 중에서 가장 큰 특징은 간결함 입니다.그런데 자바에는 함수 객체를 심지어 람다보다도 더 간결하
자바가 람다를 지원하면서 API를 작성하는 모범 사례도 크게 바뀌었다.예컨데 메서드를 재정의해 원하는 동작을 구현하는 템플릿 메서드 패턴대신, 함수 객체를 매개변수로 받는 형태를 취하는 형식으로 바뀌었다.지금부터 템플릿 메서드 패턴에서 람다 표현식으로 바꾸는 예제가 나
스트림을 사용해야할 때와 그렇지 않을때를 구분하라 스트림 API의 추상 개념 두가지원소의 유한 혹은 무한의 시퀀스스트림 파이프라인파이프라인은 단계별 출력이 다음 단계의 입력값이 되는 형태로 이어지는 구조를 말함.파이프라인은 지연 평가(lazy evaluation) 라는
핵심은 계산을 일련의 변환(transformation)으로 재구성하는 부분이다 각 변환 단게는 가능한 한 이전 단계의 결과를 받아 처리하는 "순수 함수"여야 함 오직 입력만이 결과에 영향을 주는 함수 가변 상태 참조 X함수 스스로도 다른 상태를 변경하지 않음 위와 같이
나중에자바 7까지는 일련의 원소를 반환하는 메서드에서 번환 타입으로 Collection, Set, List와 같은 컬렉션 인터페이스(기본) 혹은 Iterable이나 배열을 사용했다.예외1 - for-each 문에서만 쓰이거나 반환된 원소 시퀀스가 일부 Collectio
자바 8부터 parallel 메서드가 추가되서 파이프라인을 병렬로 실행할 수 있는 스트림을 지원했다.때문에 동시성 프로그램을 쉽게 작성할 수 있지만 주의해야 할 점이 있다.예컨데, Stream.iterate이나 limit과 parallel은 잘 어울리지 못한다.예제가
빠르게 실패하기 vs 안전하게 실패하기가능한 에러는 빠르게 처리하는 편이 좋다과거 프로그래머들은 빠르게 실패하는데에서 생기는 잇점을 생각하지 못했기 때문에 안전하게 실패하는 쪽으로 프로그램을 구성했다.안전하게 실패하는 시나리오에서는 사이드 이펙트가 나올수 있는 케이스가
매개변수 타입을 만드는데 인색하지 않는다 입니다.여러 메서드를 위한 값을 한 매개변수 타입에 우겨 넣지 않습니다.여러 메서드에서 필요한 값만 매개변수로 받습니다.항상 표준 명명 규칙을 따르는 것이 좋다고 합니다.이해할 수 있고, 같은 패키지에 속한 다른 이름들과 일관되

다중정의(오버로딩)된 세 classify 중, 어느 메서드를 호출할지가 "컴파일 타임"에 정해지기 때문 위 예제는 런타임에는 타입이 매번 달라질 수 있지만, 컴파일 타임에는 무조건 Collection<?>타입이다.즉, 호출할 메서드를 선택하는 데는 런타임 때의 타
가변인수(varagas) 메서드는 명시한 타입의 인수를 0개 이상 받을 수 있다. 인수의 개수와 길이가 같은 배열을 만든다.인수들을 이 배열에 저장하여 가변인수 메서드에 건네준다.인수의 갯수는 런타임에 배열의 길이로 알 수 있다.위 코드는 문제가 있는 코드이다.가장 심
null을 반환할 경우, 클라이언트는 null을 처리하는 코드를 추가로 작성해야 한다.null처리를 외부에서 해줘야 하므로 코드가 지저분 해진다.운좋게 오류가 안나다가, 수 년 후에나 오류가 발생하기도 한다.성능 분석 결과, 성능 저하의 주범이라고 확인되지 않는 한,
자바 8 이전에는 반환값이 없을때 취할 수 있는 선택지가 2가지가 있었다.예외 던지기null을 반환하기두가지 다 문제점을 가지고 있다. 예외를 던지는 선택지는 예외를 생성할때 비용이 많이 든다. null을 반환하는 선택지는 비용의 문제에선 자유로울 수 있지만,이런
API 문서화 유틸리티 라고 불리며, 소스코드 파일에서 문서화 주석이라는 특수한 형태로 설명을 추려 API 문서로 변환해 준다고 합니다.API를 올바로 문서화하려면 공개된 모든 클래스, 인터페이스, 메서드, 필드 선언에 문서화 주석을 달아야 된다는 것입니다.메서드 주석