목록분류 전체보기 (181)
초보개발자 긍.응.성
equals 메서드는 재정의하기에 쉬워 보이지만 곳곳에 함정이 도사리고 있다. 우선적으로 equals 메서드를 재정의하지 않아도 될 경우를 살펴보고, 재정의가 필요하다면 어떤 규약을 지켜서 재정의해야 하는지 알아보자. equals 메서드를 재정의 할 필요가 없을 때 다음 열거한 상황 중 하나에 해당된다면 equals 메서드를 재정의하지 않는것이 좋다. 각 인스턴스가 본질적으로 고유하다. 값을 표현하는것이 나닌 동작하는 개채를 표현하는 클래스가 여기에 해당된다. 예시로 Thread와 같은 클래스가 여기 해당된다. Object의 equals 메서드는 이미 이러한 클래스에 딱 맞게 구현되어있다. 인스턴스의 논리적 동치성(logical equality)을 검사할 일이 없다. 인스턴스의 논리적인 동치성을 검사해야..
자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많다. 자원 닫기는 클라이언트가 놓치기 쉬워서 예측할 수 없는 성능 문제로 이어지기 쉽다. 또한 안전망으로 사용하는 방법인 finalizer는 믿을만하지 못하다. try-finally 전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 쓰였다. static String firstLineOfFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { br.close(); } } 하지만 위의 코드에는 문제점이 존재한다. 예외는..
자바는 두 가지 객체 소멸자를 제공한다. finalizer와 cleaner이며 해당 소멸자의 사용은 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요하다. 파괴자 자바의 finalizer와 cleaner는 C++에서의 파괴자(destructor)와 다른 개념이다. C++의 파괴자는 특정 객체와 관련된 자원을 회수하는 보편적인 방법임에 반해 자바에서는 가비지 컬렉터가 그 작업을 담당하고, 프로그래머에게는 아무런 작업도 요구하지 않는다. C++의 파괴자는 비 메모리 자원을 회수하는 용도로도 쓰인다. 하지만 자바에서는 try-with-resources와 try-finally를 사용해 해결한다. finalizer와 cleaner는 즉시 수행된다는 보장이 없다. 객체에 접근할 수 없게 된 후 fin..
C와 Java의 가장 큰 차이점이라면 메모리 관리와 가비지 컬렉터라고 말할 수 있다. 가비지 컬렉터는 다 쓴 객체를 알아서 회수해가기에 메모리를 직접 관리할 필요가 없다. 그렇다고 메모리 관리에 더 이상 신경을 쓰지 않아도 된다고 생각할 수 있지만, 이번 아이템은 절대 그렇게 생각해서는 안된다는 것을 말하고 있다. 아래와 같이 구현한 Stack 클래스를 보자 public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITAL_CAPACITY]; } // p..
똑같은 기능의 객체를 매번 생성하기보다는 객체 하나를 재사용하는 편이 나을 때가 많다. 재사용은 빠르고 세련되다. 특히 불변 객체는 언제든 재사용 가능하다. 아래는 불필요한 객체 생성의 극단 적인 예시이다. String s = new String("I'm Son"); // 절대 사용하지 말 것! 위 문장은 실행될 때 마다 새로운 String 인스턴스를 새로 생성한다. 인자로 넣어주는 I'm Son과 정확히 같은 문자열을 쓸데없이 만들어 낸다. String s = "I'm Son"; 이 코드는 실행될때 하나의 String 인스턴스를 사용한다. 또한 이 방식을 사용한다면 같은 JVM안에서 이와 똑같은 문자열 리터럴을 사용하는 모든 코드가 같은 객체를 재사용한다. 생성자 대신 정적 팩토리 메서드로! 생성자 대..
많은 클래스는 하나 이상의 자원에 의존한다. 그리고 이런 클래스들을 정적 유틸리티 클래스나 싱글턴 방식으로 만들어 사용하는 모습을 볼 수 있다. 하지만 그런 방법은 좋은 방법이 아니다. 맞춤법 검사 로직을 담고 사전이라는 자원(resource)에 의존하는 클래스를 다음과 같은 방법으로 만들었을 때를 살펴보자. 차례대로, 정적 유틸리티 클래스와 싱글턴 방식의 예시이다. 정적 유틸리티 클래스 public class SpellChecker { private static final Lexicon dictionary = ...; private SpellChecker() {} // 객체 생성 방지 public static boolean isValid(String word) { ... }; public static ..