클라이언트가 클래스의 인스턴스를 얻는 수단은 public 생성자다. 하지만, 그 클래스의 인스턴스를 반환하는 단순한 정적 메서드를 통해서 이를 가능하게 할 수 있다. 생성자에 넘기는 매개변수와 생성자 자체만으로는 반환될 객체의 특성을 제대로 설명하지 못한다. 하지만,
기존의 생성자나 팩토리 메소드는 매개변수의 양이 많아지면 이를 컨트롤하기 어려웠다. 멤버변수의 양이 늘어나면 이를 수습하기가 어려워지기 때문이다. 이런 경우 우리는 빌더 패턴을 사용할 수 있다. 이 클래스는 기본적으로 불변이며, 모든 매개변수의 기본값들을 한곳에 모아
싱글턴이란 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다. 대표적으로 함수와 같은 무상태 객체나 설계상 유일해야 하는 시스템 컴포넌트를 들 수 있다. 하지만, 클래스를 싱글턴으로 만들 시 이를 사용하는 클라이언트를 테스트하기 어려워질 수 있다. 타입을 인터페이
정적 메서드와 정적 필드만을 담은 클래스를 만들고 싶을 때 (java.lang.Math or java.util.Arrays or java.util.Collections 같은 기본 타입 값이나 배열 관련 메서들을 모아놓거나 특정 인터페이스를 구현하는 객체를 생성해주는 정
많은 클래스들이 하나 이상의 자원에 의존하곤한다. 가령 맞춤법 검사기는 사전에 의존하는데, 이런 클래스를 정적 유틸리티 클래스로 구현한 모습을 드물지 않게 볼 수 있다.<정적 유틸리티를 잘못 사용한 예><싱글턴을 잘못 사용한 예>두 방식 모두 사전을 단 하
똑같은 기능의 객체를 매번 생성하기보다는 객체 하나를 재사용하는 편이 나을 때가 많다.두 번째 코드는 새로운 인스턴스를 매번 만드는 대신 하나의 String 인스턴스를 사용한다. 이 방식을 사용하면 같은 가상 머신 안에서 이와 똑같은 문자열 리터럴을 사용하는 모든 코드
자바는 C,C++과 달리 가비지 컬렉터가 다 쓴 객체를 알아서 회수해 메모리를 자동으로 관리해준다. 마치 프로그래머는 이를 신경쓸 필요가 없어보이지만 전혀 그렇지 않다.위 코드는 간단한 스택을 구현한 것인데 스택이 커졌다가 줄어들 때 스택에서 꺼낸 객체들을 가비지 컬
잘 구현된 컴포넌트의 조건은 모든 내부 구현을 완벽히 숨겨, 구현과 API를 깔끔히 분리하는 것이다. 오직 API로만 통신을 해 내부 동작 방식에는 개의치 않게 하는 것이다. 이것이 바로 캡슐화의 개념이다.캡슐화의 장점은 다음과 같다.여러 컴포넌트를 병렬로 개발해 시
자바에는 두 가지 객체 소멸자인 finalizer, cleaner가 존재한다. finalizer는 나름의 쓰임새가 있긴하지만, 쓰지 않는 것이 좋다. 그래서 자바9에서는 finalizer를 deprecated API로 지정하고 cleaner를 그 대안으로 지정했지만,
자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야하는 자원이 많다. InputStream, OutputStream, java.sql.Connection 등이 그렇다. 상당 수가 finalizaer를 통해 이를 예방하려고 하지만 그리 믿을만하진 못하다. 전통적
equals 메서드는 몇 가지 규약을 제대로 지키지 않을 경우 의도와 다르게 동작하여 프로그램에 오류를 발생시킬 수 있다. 재정의하지 않고 그냥 두면 그 클래스의 인스턴스는 오직 자기 자신과만 같게 된다. 각 인스턴스가 본질적으로 고유한 경우예컨대 Thread는 값이
equals를 재정의한 클래스는 모두 hashCode도 재정의해야 한다. 그렇지 않으면 hashCode 일반 규약을 어기게 되어 해당 클래스의 인스턴스를 HashMap이나 HashSet 같은 컬렉션 원소로 사용할 때 문제가 될 수 있다.equals 비교에서 사용되는 정
Object의 기본 toString 메서드는 잘 알다시피 우리가 작성한 클래스에 적합한 문자열을 반환하는 경우는 거의 없다. 클래스\_이름@16진수로\_표시한\_해시코드로나 반환될 것이다.toString 일반 규약에 따르면 간결하면서 사람이 읽기 쉬운 형태의 유익한 정