728x90
728x90
equals 메서드는 재정의하기 쉬워 보이지만 곳곳에 함정이 도사리고 있다. 문제를 회피하는 가장 쉬운 방법은 아예 재정의하지 않는 것이다. 그냐 두면 그 클래스의 인스턴스는 오직 자기 자신과만 같게 된다. 그러니 아래와 같은 상황 중 하나에 해당한다면 재정의하지 않는 것이 최선이다. 각 인스턴스가 본질적으로 고유하다. 값을 표현하는 게 아니라 동작하는 개체를 표현하는 클래스가 여기 해당한다. Thread가 좋은 예로, Object의 equals 메서드는 이러한 클래스에 딱 맞게 구현되었다. 인스턴스의 '논리적 동치성(logical equlity)'을 검사할 일이 없다. 예컨대 java.util.regex.Pattern은 equals를 재정의해서 두 Pattern의 인스턴스가 같은 정규표현식을 나타내는지..
자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많다. InputStream, OutputStream, java.sql.Connection 등이 좋은 예다. 자원 닫기는 클라이언트가 놓치기 쉬워서 예측할 수 없는 성능 문제로 이어질 수도 있다. 이런 자원 중 수 상당수가 안전망으로 finalizer를 활용하고는 있지만 finalizer는 그리 믿을만하지 못하다. 전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 쓰였다. 예외가 발생하거나 메서드에서 반환되는 경우를 포함해서 말이다. static String firstLineOfFile(String path) throws IOException { BufferedReader br = new BufferedRea..
자바는 두 가지 객체 소멸자를 제공한다. 그중 finalizer는 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요하다. 오동작, 낮은 성능, 이식성 문제의 원인이 되기도 한다. finalizer는 나름의 쓰임새가 몇 가지 있긴 하지만 기본적으로 '쓰지 말아야' 한다. 그래서 자바 9에서는 finalizer를 사용 자제 API로 지정하고 cleaner를 그 대안으로 소개했다(하지만 자바 라이브러리에서도 finalizer를 여전히 사용한다). cleaner는 finalizer보다는 덜 위험하지만, 여전히 예측할 수 없고, 느리고, 일반적으로 불필요하다. 자바의 finalizer와 cleaner는 C++의 파괴자(destructor)와는 다른 개념이다. C++에서의 파괴자는 (생성자의 꼭 필요..
C, C++처럼 메모리를 직접 관리해야 하는 언어와는 달리, 자바는 가비지 컬렉터를 가지고있다. 다 쓴 객체를 알아서 회수해가니 얼마나 편리하겠는가? 하지만 이를 자칫 메모리 관리에 더 이상 신경 쓰지 않아도 된다고 오해할 수 있는데, 절대 그렇지 않다. 아래의 코드는 스택을 간단히 구현한 코드이다. public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Object e) { ensure..
벌써 한빛미디어 서평단 활동 3번째 개발 서적이다. 이번 서적은 웹 개발자라면 꼭 공부해야하는 봄.... 스프링이다!! 주 언어가 Java이고 웹 개발자를 지망한다면 Spring은 꼭 공부해야 할 것이고 Spring MVC도 어느정도의 숙련도를 요구한다. (필요한 만큼 알면 된다고 하는데, 더 고급진 개발자가 되고싶다면 다다익선이다) 스프링 자체는 워낙 방대한 내용이기 때문에 전부 다 챙기다는건 쉽지 않을 것이다. 스프링은 객체지향 프로그래밍을 도와주는 프레임워크다. 객체지향설계를 공부하면서 스프링을 공부한다면 더 많이 와닿을 것이다. 어느 자바 웹 개발자 박OO 차장 대략적인 박차장의 개발인생 그렇다 웹 개발자라면... (Node 라거나.... Angular 라거나... Python은 잘 모르겠다) 스..
이전글에 이어서 아이템6의 내용을 정리한다. 똑같은 기능의 객체를 매번 생성하기보다는 객체 하나를 재사용하는 편이 나을때가 많다. 재사용은 빠르고 세련됐다. 특히 불변 객체는 언제든 재사용할 수 있다. 다음 코드는 하지 말아야 할 극단적인 예이다. 자세히 살펴보고 절대 따라하지 말자 String s = new String("bikini"); // 따라 하지 말 것! 이 문장은 실행될 때마다 String 인스턴스를 새로 만든다. 완전히 쓸데없는 행위다. 생성자에 넘겨진 "bikini" 자체가 이 생성자로 만들어내려는 String과 기능적으로 완전히 똑같다. 이 문장이 반복문이나 빈번히 호출되는 메서드 안에 있다면 쓸데없는 String인스턴스가 수백만 개 만들어질 수도 있다. 개선된 버전을 보자 String..