[아이템 10] equals는 일반 규약을 지켜 재정의하라

equals 메서드를 재정의하는 이유는 논리적 동치성을 비교하기 위함입니다. 논리적 동치성이란 객체의 참조값이 아닌 객체의 값이 같은지를 판단하는 것입니다. equals 메서드를 올바르게 재정의하지 않으면 객체 비교에서 예기치 않은 문제가 발생할 수 있습니다. equals메서드를 오버라이딩 할 때는 다음의 규약을 따라야 합니다. 1. equals 규약 1) 반사성 (Reflexivity) null이 아닌 모든 참조 값 x에 대해, x.equals(x)는 true입니다. 2) 대칭성 (Symmetry) null이 아닌 모든 참조 값 x, y에 대해 x.equals(y)는 y....

[아이템 9] try-finally보다는 try-with-resources를 사용하라

자바에는 InputStream, OutputStream, java.sql.Connection과 같은 직접 닫아줘야 하는 자원들이 존재합니다. 이 자원들을 제대로 닫지 않으면 메모리 누수와 같은 심각한 문제를 초래할 수 있습니다. 📌 실수를 유발할 수 있는 기존 코드 자바에서는 자원을 사용한 후 반드시 해제해야 하므로, 이전에는 try-finally를 사용하여 자원을 해제하는 방식이 흔했습니다. 하지만 이 방식은 복잡하고 오류를 유발할 가능성이 있습니다. 1 2 3 4 5 6 7 8 9 static String firstLineOfFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br....

[아이템 8] finalizer와 cleaner 사용을 피하라

1. finalizer와 cleaner란? 자바에서는 객체 소멸 시 특정 작업을 수행하는 두 가지 방법, finalizer와 cleaner를 제공합니다. finalizer는 Java 9부터 deprecated로 지정되었으며, cleaner는 그 대안으로 제공되지만 여전히 예측 불가능하고 성능 문제가 있습니다. 2. finalizer와 cleaner의 문제점 2.1 언제 실행될지 알 수 없다 finalizer와 cleaner는 즉시 실행된다는 보장이 없습니다. 이들은 가비지 컬렉션이 수행될 때 동작하지만, 그 시점을 예측할 수 없기 때문에 시간에 민감한 작업을 이들에 의존할 수 없습니다. 2.2 finalizer의 느린 실행 finalizer는 lazy하게 실행됩니다....

[아이템 7] 다 쓴 객체 참조를 해제하라

1. 메모리 누수가 발생하는 예시 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 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 Object pop() { if (size == 0) throw new EmptyStackException(); return elements[--size]; // 메모리 누수 발생 가능 } private void ensureCapacity() { if (elements....

[아이템 6] 불필요한 객체 생성을 피하라

객체를 생성할 때 기능이 동일한 객체를 매번 새로 생성하기보다는 객체를 재사용하는 것이 성능과 메모리 효율성 측면에서 더욱 적절합니다. 특히 **불변 객체(immutable objects)**는 항상 재사용이 가능하므로 이를 적극 활용해야 합니다. 📌 문자열 생성 방법 객체 생성 방식 - 피해야 되는 예시 1 String str = new String("hello"); 이 방식은 매번 새로운 객체를 생성합니다. 같은 문자열을 사용하더라도 매번 새로운 인스턴스가 만들어져 낭비가 발생합니다. 리터럴 방식 1 String str = "hello"; 이 방식은 리터럴을 사용하여 JVM이 동일한 문자열을 캐싱하므로, 이미 같은 문자열이 있다면 이를 재사용합니다....