☕️ Java

equals 메서드는 재정의하기 쉬워 보이지만, 실제로 재정의 할 때는 주의해야 할 점이 많다. 이 문제를 회피하려면 그냥 equals를 재정의하지 않으면 된다. 재정의하지 않고 그냥 둔다면, 해당 클래스의 인스턴스는 오직 자기 자신과만 같게 된다. 다음은 equals를 재정의하지 않는 것이 최선인 경우들이다. 각 인스턴스가 본질적으로 고유하다. 값을 표현하는 게 아니라 동작하는 개체를 표현하는 클래스가 여기 해당한다. Thead가 좋은 예로, Object의 equals 메서드는 이러한 클래스에 딱 맞게 구현되었다. 인스턴스의 논리적 동치성(logical equality)을 검사할 일이 없다. 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다. 예를 들어 대부분의 Set 구현체는 Ab..
try-finally는 사용하는 자원이 많아질수록 코드가 지저분해진다. 이건 많이들 경험해 보았을 것이다. static String firsLineOfFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { br.close(); } } 위 코는 별로 나쁘지 않아보인다. 하지만 자원을 하나 더 쓴다면 어떨까? static void copy(String src, String dst) throws IOException { InputStream in = new FileInputStream(src); try{ Output..
자바에서는 객체 소멸자로 finalizer와 cleaner를 제공하지만, 모두 예측할 수 없고, 상황에 따라서는 위험할 수도 있다. (자바 9에서는 finalizer를 Deprecated로 정하고, 대안으로 cleaner를 냈지만, cleaner도 역시 예측할 수 없다.) finalizer와 cleaner 모두 즉시 실행된다는 보장이 없고. 언제 실행될지 알 수 있는 방법이 없기 때문에 finalizer와 cleaner로는 제때 실행되어야 하는 작업은 절대 할 수 없다. 즉 요약하자면, 상태를 영구적으로 수정하는 작업에서는 절때 finalizer와 cleaner에 의존해서는 안 된다는 것이다. 예를 들면 데이터베이스 같은 공유 자원의 영구 락(lock)의 해제를 finalizer와 cleaner에 맡겨 ..
자바는 가비지 컬렉터가 있으므로, 개발자는 메모리 관리에 신경쓰지 않아도 된다고 오해할 수 있으나, 사실을 전혀 그렇지 않다. 물론 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){ ensureCapacity(); elements[size++] = e; } public ..
똑같은 기능의 객체를 매번 생성하기보다는 객체 하나를 재사용하는 편이 나을 때가 많다. 재사용은 빠르고 세련되다. 특히 불변 객체는 언제든지 재사용할 수 있다. 다음 코드는 하지 말아야 할 극단적인 예시이다. String s = new String("신동훈"); 이 문장은 실행될 때마다 String 인스턴스틀 새로 만든다. 완전히 쓸데없는 행위다. 생성자에 넘겨진 "신동훈" 자체가 이 생성자로 만들어내려는 String과 기능적으로 완전히 똑같다. 이 문장이 반복문이나 빈번하게 호출되는 메서드 안에 있다면 쓸데없는 String 인스턴스가 수백만 개 만들어질 수도 있다. String s = "신동훈"; 이 코드는 새로운 인스턴스를 매번 만드는 대신 하나의 String 인스턴스를 사용한다. 이에 관련되서는 아..
대부분의 클래스들은 하나 이상의 자원(클래스)에 의존한다. 책에서는 맞춤법 검사기를 예로 들었는데, 한번 살펴보자. 여기 사전에 의존하는 맞춤법 검사기가 있다. 정적 유틸리티를 잘못 사용한 예 public class SpellChecker { private static final Lexicon dictionary = new Lexicon(); private SpellChecker() {} //객체 생성 방지 public static boolean isValid(String word){ //... } public static List suggestions(String typo){ //... } } 위처럼 SpellChecker를 정적 유틸리티 클래스로 만들면 유연하지 않고 테스트하기가 어렵다. 싱글턴을 잘..
개발을 하다 보면 단순히 정적 메서드와 정적 필드만을 담은 클래스(유틸리티 클래스)를 만들고 싶을 때가 있을 것이다. 객체 지향적으로 사고하지 않는 이들이 종종 남용하는 방식이기에 그리 곱게 보이지는 않지만 분명 나름의 쓰임새가 있다. 예컨대 java.lang.Math와 java.util.Collections처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드(혹은 팩터리)를 모아놓을 수도 있다. 마지막으로 final 클래스와 관련한 메서드들을 모아놓을 때도 사용한다. final 클래스를 상속해서 하위 클래스에 메서드를 넣는 건 불가능하기 때문이다. 만약 정적 멤버만 담은 유틸리티 클래스를 만들 때, 생성자를 명시하지 않으면 컴파일러가 자동으로 기본 생성자를 만들어준다. 하지만 우리는 유틸리티 ..
싱글턴(Singleton)이란 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다. 싱글턴에 대해서는 필자가 정리해 둔 글을 참고하자. [Spring] 싱글톤 컨테이너 (feat. 싱글톤을 구현하는 여러 방식) 싱글톤 싱글톤 패턴은 어떤 클래스의 인스턴스가 오직 하나만 생성되는 것을 보장하며, 이 인스턴스에 접근할 수 있는 전역적인 접촉점을 제공하는 패턴이다. 싱글톤 구현 1. Eager Initialization (이 ttl-blog.tistory.com 클래스를 싱글톤으로 만들면, 이에 대한 테스트코드 작성이 어려워질 수 있다. 타입을 인터페이스로 정의한 다음 그 인터페이스를 구현해서 만든 싱글턴이 아니라면 싱글턴 인스턴스를 가짜(Mock) 구현으로 대체할 수 없기 때문이다. 싱글턴을 구현하는 방..
말 랑
'☕️ Java' 카테고리의 글 목록 (5 Page)