hashCode()와 equals()를 같이 오버라이딩해야 하는 이유
·
Java
`hashCode()`와 `equals()`는 Object 클래스에 선언된 메서드며, 모든 객체가 사용할 수 있다.두 메서드는 같이 오버라이딩해야 하는 이유가 있다. 그 이유를 알아보자. 일단 `hashCode()`와 `equals()`부터 알아보자. JDK 21 기준 public class Object { @IntrinsicCandidate public native int hashCode(); public boolean equals(Object obj) { return (this == obj); }} hashCode()객체의 해시 값을 반환한다.메모리 주소와 무관한 난수 값을 사용해서 해시를 생성하는 해시 함수다. 해시가 뭘까? 해시 함수부터 알아보자. 해시 함수..
ConcurrentHashMap의 동작원리
·
Java
ConcurrentHashMap은 실무에서 처음 사용해 봤었다. 코드리뷰를 진행하다가 HashMap을 사용한 코드에 대해서 Thread-Safe한 HashMap인 ConcurrentHashMap을 사용해야 한다고 피드백을 받았다. 그 후로 동시성 문제가 발생할 만한 곳은 ConcurrentHashMap을 사용하여 해결했다.그러다 문득 동시성 문제를 어떻게 해결하는지 궁금해져서 파헤쳐 보기로 했다. JDK 21 기준 일단 키-값 쌍 구조인 HashTable을 구현한 클래스는 크게 3가지가 있다.HashMap (Thread-Unsafe)HashTable (Thread-Safe)ConcurrentHashMap (Thread-Safe) ConcurrentHashMap이 Thread-Safe한 HashMap..
제네릭 타입 소거 (Type Erasure)
·
Java
제네릭은 타입 안정성을 보장하기 위해 JDK 1.5부터 도입됐으며, 이전 자바 버전의 코드와의 호환성을 위해 컴파일 타임에 제네릭 타입은 사라진다.제네릭의 작동 방식public class Node { private T data; private Node next; public Node(T data, Node next) { this.data = data; this.next = next; } public T getData() { return data; } // ...}제네릭 타입인 `Node` 클래스는 컴파일되면 아래 코드로 변환된다. public class Node { private Object data; private Node next; ..
ArrayList는 왜 제네릭 타입 E[]가 아닌 Object[]으로 요소를 관리할까?
·
Java
제네릭을 공부하다가 제네릭을 사용하는 클래스 중 대표적으로 자주 사용되는 ArrayList에 대해 파헤치기 시작했다.그런데 이상한 점을 하나 발견했다.내부 요소들을 관리하는 자료구조가 Object[] 이었던 것이다.ArrayList가 제네릭을 사용하니 E[] 를 사용해도 될 것 같은데, 왜 Object[] 를 사용하고 있을까? ArrayList제네릭을 이용해 구현한 ArrayListprivate static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initial..