본문 바로가기

프로그래밍(TA, AA)/JVM 언어

[자바] 자바를 잘 사용하기 위한 78가지 규칙


이펙티브 자바 2판에 수록된 내용입니다. 각 규칙에 대한 상세내용은 대중교통 오고가는 시간에 차례차례 읽어나가고 있습니다.


java로 이런저런 개발시 단순히 문법 나열이 아닌, 잘 만들어진 SW를 작성하는데에 아주 유용한 팁이 될 것 같습니다. java 언어에 이런 기능이 있는데, 어떤 상황에서 어떠한 이유를 이런 것을 쓴다는 것을 아는 것은 매우 중요하다고 생각하며, 아래 규칙들을 또 정리하다보니 그동안 잘짜려고 노력했던 코드들이 상당부분 아래 규칙과 맞아떨어지는 부분들도 있었던 것 같습니다. 아래 규칙을 정의한 이펙티브 자바 저자는 더많은 경험과 지식을 갖고있는 훌륭한 개발자이니만큼 주니어개발자로서 모르는 부분은 배워서 실무에서 적용해보려고 합니다.


자바 코딩시 명료함(clarity)과 단순함(simplicity)은 가장 중요한 덕목입니다. 각 모듈은 사용자가 예상할 수 없는 방식으로 동작해서는 안됩니다. 가능한 작아야 하지만, 그렇다고 너무 작아져서는 곤란합니다. 모듈이라는 용어는 재사용 가능한 컴포넌트를 지칭하는 것으로, 개별 메서드뿐 아니라 여러 패키지로 구성된 복잡한 시스템까지를 아우릅니다. 코드는 복사하기보단 재사용해야합니다. 모듈 간 의존성은 가능한 한 줄이여야 합니다. 오류는 코드에 끼어든 즉시, 바람직하게는 컴파일 시점에 탐지될 수 있어야 합니다.


자바는 네 가지 유형의 자료형(type)을 지원합니다. 인터페이스(interface, 어노테이션을 포함한다), 클래스(class, 열거 자료형enum을 포함한다), 배열(array), 그리고 기본 자료형(primitive) 등입니다. 이 가운데 처음 세가지는 참조 자료형(reference type)이라는 이름으로 알려져 있습니다. 클래스로 만든 개체(instance)와 배열은 객체(object)입니다.


공개 API(exported API)라는 용어는 단순히 API라고도 하는데, 프로그래머들이 클래스, 인터페이스, 패키지를 사용할 때 이용하는 클래스, 인터페이스, 생성자, 멤버, 그리고 직렬화 형식(serialized form)을 가리키는 말입니다. API를 사용해 프로그램을 작성하려는 프로그래머는 API의 사용자(user)라고 지칭합니다. 어떤 API를 사용해 구현된 클래스는 API의 클라이언트(client)라고 부릅니다.



객체의 생성과 삭제

규칙1 생성자 대신 정적 팩토리 메서드를 사용할 수 없는지 생각해보라

규칙2 생성자 인자가 많을 때는 Builder 패턴 적용을 고려하라

규칙3 private 생성자나 enum 자료형은 싱글턴 패턴을 따르도록 설계하라

규칙4 객체 생성을 막을 때는 private 생성자를 사용하라

규칙5 불필요한 객체는 만들지 말라

규칙6 유효기간이 지난 객체 참조는 폐기하라

규칙7 종료자 사용을 피하라


모든 객체의 공통 메서드

규칙8 equals를 재정의할 때는 일반 규약을 따르라

규칙9 equals를 재정의할 때는 반드시 hashCode도 재정의하라

규칙10 toString은 항상 재정의하라

규칙11 clone을 재정의할 때는 신중하라

규칙12 Comparable 구현을 고려하라


클래스와 인터페이스

규칙13 클래스와 멤버의 접근 권한을 최소화하라

규칙14 public 클래스 안에는 public 필드를 두지 말고 접근자 메서드를 사용하라

규칙15 변경 가능성을 최소화하라

규칙16 계승하는 대신 구성하라

규칙17 계승을 위한 설계와 문서를 갖추거나, 그럴 수 없다면 계승을 금지하라

규칙18 추상 클래스 대신 인터페이스를 사용하라

규칙19 인터페이스는 자료형을 정의할 때만 사용하라

규칙20 태그 달린 클래스 대신 클래스 계층을 활용하라

규칙21 전략을 표현하고 싶을 때는 함수 객체를 사용하라

규칙22 멤버 클래스는 가능하면 static으로 선언하라


제네릭

규칙23 새 코드에는 무인자 제네릭 자료형을 사용하지 마라

규칙24 무점검 경고(unchecked warning)을 제거하라

규칙25 배열 대신 리스트를 써라

규칙26 가능하면 제네릭 자료형으로 만들 것

규칙27 가능하면 제네릭 메소드로 만들 것

규칙28 한정적 와일드카드를 써서 API 유연성을 높여라

규칙29 형 안전 다형성 컨테이너를 쓰면 어떨지 따져보라


열거형(enum)과 어노테이션

규칙30 int 상수 대신 enum을 사용하라

규칙31 ordinal 대신 객체 필드를 사용하라

규칙32 비트 필드(bit field) 대신 EnumSet을 사용하라

규칙33 ordinal을 배열 첨자로 사용하는 대신 EnumMap을 이용하라

규칙34 확장 가능한 enum을 만들어야 한다면 인터페이스를 이용하라

규칙35 작명 패턴 대신 어노테이션을 사용하라

규칙36 Override 어노테이션은 일관되게 사용하라

규칙37 자료형을 정의할 때 표식 인터페이스를 사용하라


메서드

규칙38 인자의 유효성을 검사하라

규칙39 필요하다면 방버적 복사본을 만들라

규칙40 메서드 시그니처는 신중하게 설계하라

규칙41 오버로딩할 때는 주의하라

규칙42 varargs는 신중히 사용하라

규칙43 null 대신 빈 배열이나 컬렉션을 반환하라

규칙44 모든 API 요소에 문서화 주석을 달라


일반적인 프로그래밍 원칙들

규칙45 지역 변수의 유효범위를 최소화하라

규칙46 for문보다는 for-each 문을 사용하라

규칙47 어떤 라이브러리가 있는지 파악하고, 적절히 활용하라

규칙48 정확한 답이 필요하다면 float와 double은 피하라

규칙49 객체화된 기본 자료형 대신 기본 자료형을 이용하라

규칙50 다른 자료형이 적절하다면 문자열 사용은 피하라

규칙51 문자열 연결 시 성능에 주의하라

규칙52 객체를 참조할 때는 그 인터페이스를 사용하라

규칙53 리플렉션 대신 인터페이스를 이용하라

규칙54 네이티브 메서드는 신중하게 사용하라

규칙55 신중하게 최적화하라

규칙56 일반적으로 통용되는 작명 관습을 따르라


예외

규칙57 예외는 예외적 상황에만 사용하라

규칙58 복구 가능 상태에는 점검지정 예외를 사용하고, 프로그래밍 오류에는 실행시점 예외를 이용하라

규칙59 불필요한 점검지정 예외 사용은 피하라

규칙60 표준 예외를 사용하라

규칙61 추상화 수준에 맞는 예외를 던져라

규칙62 메서드에서 던져지는 모든 예외에 대해 문서를 남겨라

규칙63 어떤 오류인지를 드러내는 정보를 상세한 메시지에 담으로

규칙64 실패 원자성 달성을 위해 노력하라

규칙65 예외를 무시하지 마라


병행성

규칙66 변경 가능 공유 데이터에 대한 접근은 동기화하라

규칙67 과도한 동기화는 피하라

규칙68 스레드보다는 실행자와 태스크를 이용하라

규칙69 wait나 notify 대신 병행성 유틸리티를 이용하라

규칙70 스레드 안전성에 대해 문서로 남겨라

규칙71 초기화 지연은 신중하게 하라

규칙72 스레드 스케줄러에 의존하지 마라

규칙73 스레드 그룹은 피하라


직렬화

규칙74 Serializable 인터페이스를 구현할 때는 신중하라

규칙75 사용자 지정 직렬화 형식을 사용하면 좋을지 따져 보라

규칙76 readObject 메서드는 방어적으로 구현하라

규칙77 개체 통제가 필요하다면 readResolve 대신 enum 자료형을 이용하라

규칙78 직렬화된 객체 대신 직렬화 프록시를 고려해 보라