본문 바로가기

이펙티브 자바

(51)
[이펙티브 자바] 아이템 11. equals를 재정의하려거든 hashcode도 재정의하라 hashcode : 객체를 대표하는 정수 값. hashCode() 메서드를 통해 이 값을 얻는다. 객체의 hashcode는 객체를 저장하거나 검색할때 hash table같은 데이터 구조의 키로 사용된다. equals를 재정의한 클래스 모두에서 hashCode도 재정의해야 한다. 그렇지 않으면 hashCode 일반 규약을 어기게 되어 오류가 발생할 수 있다. 1. 프로그램 실행 중 동일한 객체에 대해 여러 번 hashCode() 메서드를 호출하면, 객체가 수정되지 않았다면 메서드는 항상 동일한 정수를 반환해야 한다. 이 값은 객체가 수정되지 않는 한 프로그램 재실행 간에도 일관되어야 한다. 2. equals(Object) 메서드가 두 객체를 동등하게 판단한다면, 두 객체의 hashCode() 메서드는 동일..
[이펙티브 자바] 아이템 10. equals는 일반 규약을 지켜 재정의하라 equals 메서드는 Java의 Object 클래스에 정의된 메서드로, 두 객체가 "같음(equal)"을 결정하기 위해 사용된다. 모든 클래스에서 상속받으므로, 필요에 따라 오버라이드(재정의)하여 객체 간의 동등성 비교 방식을 커스텀할 수 있다. 기본 동작 : public boolean equals(Object obj) { return (this == obj); } 기본적으로 Object 클래스의 equals 메서드는 두 객체의 참조가 같은지 확인한다. 즉, 두 참조가 메모리 상에서 같은 객체를 가리키는 경우에만 true를 반환한다. equals를 재정의할 때 다음 중 하나라도 해당한다면 재정의하지 않는것이 좋다. 1. 각 인스턴스가 본질적으로 고유하다. 예를들어 Thread 클래스가 있다. Thread..
[이펙티브 자바] 아이템 9. try-finally보다는 try-with-resources를 사용하라 try-finally 사용 예시 (비효율적) import java.io.*; public class TryFinallyExample { public static String firstLineOfFile(String path) throws IOException { BufferedReader br = null; try { br = new BufferedReader(new FileReader(path)); return br.readLine(); } finally { if (br != null) { br.close(); // 자원을 명시적으로 해제해야 함 } } } } 이 예시에서는 finally 블록을 사용해 파일 리더를 명시적으로 닫아야한다. 번거로울 뿐만 아니라 close 메서드에서 예외가 발생하면 원래의..
[이펙티브 자바] 아이템 8. finalizer와 cleaner 사용을 피하라 자바는 두 가지 객체 소멸자를 제공한다. finalizer는 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요하다. cleaner는 finalizer보다는 덜 위험하지만, 여전히 예측할 수 없고, 느리고, 일반적으로 불필요하다. 사용 예시 : public class ProblematicResourceHolder { private SomeResource resource; public ProblematicResourceHolder(String resourceName) { this.resource = new SomeResource(resourceName); } // Finalizer를 사용한 자원 해제 시도 - 사용을 피해야 함! @Override protected void finalize() ..
[이펙티브 자바] 아이템 7. 다 쓴 객체 참조를 해제하라 자바의 가비지 컬렉션(garbage collection) 메커니즘이 자동으로 메모리 관리를 해주더라도, 더 이상 사용하지 않는 객체에 대한 참조를 계속 유지하는 것은 메모리 누수(memory leak)를 일으킬 수 있다. 특히, 컬렉션 객체 같은 경우는 개발자가 명시적으로 객체 참조를 해제하지 않으면, 의도치 않게 메모리 누수가 발생할 수 있다. 스택 구현에서의 메모리 누수 방지 예시 : public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIA..
[이펙티브 자바] 아이템 6. 불필요한 객체 생성을 피하라 똑같은 기능의 객체를 매번 생성하기 보다는 객체 하나를 재사용하는 편이 나을 때가 많다. 예시 : 문자열 인스턴스의 불필요한 생성 피하기 비효율적인 예 public String repeat(String str, int count) { String result = ""; for (int i = 0; i < count; i++) { result += str; // 매 반복마다 새로운 String 객체 생성 } return result; } 효율적인 예 public String repeat(String str, int count) { StringBuilder result = new StringBuilder(); for (int i = 0; i < count; i++) { result.append(str); /..
[이펙티브 자바] 아이템 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식을 사용하는 경우가 자주 있는데 이는 적합하지 않다. 인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방식인 의존 객채 주입 패턴이 좋다. 예시 : // 주문 처리를 담당하는 클래스 public class OrderProcessor { // 결제 서비스에 대한 의존성 private final PaymentService paymentService; // 재고 서비스에 대한 의존성 private final InventoryService inventoryService; // 생성자를 통한 의존 객체 주입 // OrderProcessor는 PaymentService와 InventoryService의 구체적인 구현에 의존하지 ..
[이펙티브 자바] 아이템 4. 인스턴스화를 막으려거든 private 생성자를 사용하라 "인스턴스화를 막으려거든 private 생성자를 사용해라"는 조언은 유틸리타 클래스나 도우미 클래스와 같이 상태를 가지지 않고 단순 메서드만을 제공하는 클래스에서 주로 사용된다. 예시 : public class UtilityClass { // private 생성자를 추가하여 인스턴스화를 방지함 private UtilityClass() { throw new AssertionError("UtilityClass should not be instantiated"); } // 유틸리티 메서드 예시 public static void utilityMethod() { // 메서드 구현 } } 예시에 나온 UtilityClass 같이 오직 메서드만을 제공할 경우 private 생성자를 추가해, 외부에서 인스턴스 생성을 ..