클래스와 멤버의 접근 권한을 최소화하라 잘 설계된 컴포넌트는 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 잘 숨긴 컴포넌트이다. 모든 내부 구현을 완벽히 숨기고, 구현과 API를 깔끔히 분리하는 것이 중요하다. 이를 정보 은닉 혹은 캡슐화라고 한다. 정보 은닉의 장점 여러 컴포넌트를 병렬로 개발할 수 있기 때문에 시스템 개발 속도를 높인다. 디버깅과 교체에 용이하여 시스템 관리 비용을 낮춘다. 다른 컴포넌트에 영향을 주지 않기 때문에 제작 난이도를 낮추고 성능 최적화와 SW 재사용에 도움을 준다. 접근 제어자 자바에서는 정보 은닉을 위해 접근을 제어하는 메커니즘을 제공한다. public : 모든 곳에 접근할 수 있다. (공개 API - 영원한 관리 필요) protected : package-pri..
Comparable을 구현할지 고려하라 객체를 정렬하기 위한 인터페이스로 자바에선 Comparable 인터페이스와 Comparator 인터페이스 두 가지가 존재 한다. 정확히는 정렬하기 위한 인터페이스라기 보단, 객체를 비교할 수 있는 인터페이스라고 보는 것이 바람직하다. public class PointTest { public static void main(String[] args) { Point a = new Point(1, 2); Point b = new Point(2, 3); } static class Point { int x, y; public Point(int x, int y) { this.x = x; this.y = y; } } } 다음과 같은 Point 객체는 부등호 비교뿐만 아니라 객체를..
clone 재정의는 주의해서 진행하라 /** * A class implements the Cloneable interface to * indicate to the {@link java.lang.Object#clone()} method that it * is legal for that method to make a * field-for-field copy of instances of that class. * * Invoking Object's clone method on an instance that does not implement the * Cloneable interface results in the exception * CloneNotSupportedException being thrown. * *..
toString을 항상 재정의하라 Object의 기본 메서드 중 toString은 재정의하지 않으면 phone@adbbd처럼 단순히 클래스명@해시코드를 표현한다. toString의 규약은 모든 하위 클래스에서 이 메서드를 재정의하라이다. toString 메서드는 객체를 println, printf, +, assert, 디버거 등 을 출력할 때 자동으로 호출된다. 즉, 직접 호출하지 않아도 사용되는 경우가 많다. 따라서 재정의는 필수적이며, 재정의 시에 객체가 가진 주요 정보를 모두 반환하는 것이 올바르다. /** * Returns a string representation of this collection. The string * representation consists of a list of the ..
equals를 재정의하려거든 hashCode도 재정의하라 equals 재정의 후 hashCode를 재정의해야 한다. 그 이유는 논리적으로 같은 객체는 같은 해시코드를 반환해야하기 때문이다. Hash 함수를 사용하는 컬렉션을 사용하지 않으면 hashCode를 재정의하지 않더라도 문제가 발생하지 않는다. 하지만 애플리케이션 레벨에서 바라봤을 때 해시 컬렉션을 사용하지 않는다고 확신하기 어렵다. 따라서 hashCode도 같이 재정의 하는 것이 필요하다. equals만 재정의 한 경우 import java.util.*; public class Car { private final String name; public Car(String name) { this.name = name; } @Override public..
equals는 일반 규약을 지켜 재정의하라 Object는 자바의 최상위 클래스이며, 모든 클래스의 부모 역할을 한다. Object의 메서드 중 equals는 보통 논리적 동치성 즉, String 이나 Integer 처럼 값 클래스 들의 주솟값이 아닌 값을 비교하기 위해 재정의 해서 사용한다. equals 재정의를 사용하지 않아도 되는 경우 각 인스턴스가 본질적으로 고유한 경우 Thread 처럼 값을 표현하는 것이 아닌 동작하는 개체를 표현하는 클래스는 Object 클래스의 equals 메서드에서 기본적으로 제공한다. 논리적 동치성(logical equality)을 검사할 일이 없는 경우 상위 클래스에서 재정의한 equals가 하위 클래스에도 적합한 경우 예를 들어 Set 인터페이스는 AbstractSet..
try-finally 보다는 try-with-resources를 사용하라 자바 라이브러리에는 InputStream, Connection 등 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많다. 자원을 닫는 것은 놓치기 쉬워 예측하기 어려운 성능 문제로 이어지기도 한다. 상당 수가 안정망으로 finalizer, cleaner 등을 활용하지만 실행을 보장하지 못한다. 예외가 발생하거나 메서드에서 반환되는 경우를 포함해서 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 쓰였다. 다음 코드 예시를 살펴보자. try-finally static String firstLineOfFile(String path) throws IOException { BufferedReader br = new Buf..
finalizer와 cleaner 사용을 피하라 자바는 finalizer 와 cleaner 두 가지로 객체 소멸자를 제공한다. 그 중 finalizer는 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요하다. cleaner는 finalizer 보다 덜 위험하지만, 여전히 예측할 수 없고, 느리며 일반적으로 불필요하다. 따라서 Java 9 에서 부터 deprecated(사용 자제) 되었으며, 그 대안으로 cleaner를 사용한다. deprecated 관련 문서 : https://docs.oracle.com/javase/9/docs/api/java/lang/Object.html#finalize-- 정리에 앞서 상태를 영구적으로 수정하는 작업에서는 절대로 두 가지의 객체 소멸자를 사용하면 안된다..