N° 01 — 목록
'Backend Development/Java' (25)
-
Backend Development/JavaJava - 13. stream
Stream 파이프라인에서 filter가 호출되지 않는 순간 — 지연 평가의 작동 원리list.stream() .filter(x -> { System.out.println("filter: " + x); return x > 5; }) .map(x -> { System.out.println("map: " + x); return x * 2; }) .findFirst();이 코드를 실행하면 전체 리스트를 순회하며 모든 요소에 filter와 map을 적용할까? — 아니다. 첫 번째로 조건을 만족하는 요소를 찾는 즉시 중단된다. findFirst()가 단 하나의 결과만 필요하므로, Stream은 그것만 계산한다. 이것이 지연 평가(lazy evaluation)다. (Stream API)지연 평가가 ..
-
Backend Development/JavaJava - 12. lambda functional
람다가 사실 익명 클래스가 아닌 이유 — 함수형 프로그래밍과 invokedynamic(x, y) -> x + y를 컴파일하면 익명 내부 클래스가 생성될까? 대부분의 Java 개발자는 그렇게 생각한다. 틀렸다. Java 8의 람다는 invokedynamic 바이트코드로 컴파일된다 — 런타임에 JVM이 람다 인스턴스를 생성하는 방법을 결정한다. (JEP-335, JLS §15.27)이 차이가 왜 중요한가? 익명 클래스는 매번 새 .class 파일을 만들고, 인스턴스를 생성할 때마다 객체를 할당한다. invokedynamic 방식은 JVM이 상황에 따라 인스턴스를 재사용하거나 동적으로 생성할 수 있어 더 효율적이다. 이 글은 람다가 실제로 어떻게 실행되는지, 메서드 참조로 코드를 어떻게 줄이는지, 그리고 "e..
-
Backend Development/JavaJava - 11. generics
List과 List가 런타임에 같은 타입인 이유 — 제네릭과 타입 소거new ArrayList().getClass() == new ArrayList().getClass() — 이 표현식은 true다. List과 List는 런타임에 같은 클래스(ArrayList)다. 제네릭 타입 정보가 컴파일 후 사라지기 때문이다 — 이것이 타입 소거(type erasure)다. (JLS §4.6)타입 소거를 모르면, 리플렉션으로 제네릭 타입을 검사하려다 실패하고, 제네릭 배열을 만들려다 컴파일 에러를 만나고, 힙 오염(heap pollution)에 빠진다. 왜 Java는 이렇게 설계했을까? 이 글은 제네릭이 컴파일 후 어떻게 사라지는지, 그리고 와일드카드(PECS)로 무엇을 하는지 풀어간다.제네릭이 해결하는 문제 — 타..
-
Backend Development/JavaJava - 10. collections
HashMap에서 7개의 키가 충돌하면 어떤 일이 일어나는가 — 컬렉션 선택의 기준HashMap에 7개의 키를 넣었다. 버킷 하나에 8번째 충돌이 발생하는 순간, 내부 데이터 구조가 연결 리스트에서 레드블랙 트리로 바뀐다. (HashMap JavaDoc) 대부분의 개발자는 이 사실을 모른 채 HashMap을 쓴다. 그래야 할까? — 대부분의 경우 그래도 된다. 하지만 성능이 갑자기 저하되거나, 메모리가 예상보다 많이 쓰일 때, 이 내부 구조를 아는 것이 문제 해결의 열쇠가 된다.왜 ArrayList는 0.001초인데 LinkedList는 1초 걸릴까? 정답은 "메모리에 어떻게 배치되어 있는가"에 있다. 이 글은 List, Set, Map, Queue 각각이 내부적으로 어떻게 동작하는지를 풀어간다.컬렉션 ..
-
Backend Development/JavaJava - 09. exception
throws Exception이 최악의 예외 처리인 이유 — 예외 계층과 자원 관리메서드 시그니처에 throws Exception이라고 적힌 코드를 본 적이 있는가. "뭔가 예외가 날 수 있는데, 구체적으로 뭔지는 모르겠고, 어차피 호출하는 쪽에서 처리해"라는 뜻이다. 이것은 예외 처리가 아니라 예외 무시다. 호출하는 쪽은 catch (Exception e)를 강제받고, 정작 복구할 수 있는 정보는 없다."복구할 수 있으면 checked, 못 하면 unchecked." — 이 한 문장이 Java 예외 시스템의 핵심이다. (JLS §11) 이 글은 checked vs unchecked의 선택 기준, try-with-resources의 자동 자원 관리, 그리고 "예외를 삼키면 안 되는 이유"를 풀어간다.예외..
-
Backend Development/JavaJava - 08. record sealed enum
보일러플레이트를 없앤 Java의 세 가지 타입 — record, sealed, enumPoint 클래스를 만든다고 하자. x, y 필드, 생성자, getter, equals, hashCode, toString — Java에서 불변 데이터 객체 하나를 제대로 만들려면 50줄이 필요했다. Lombok @Value로 줄여봤지만, 그것은 서드파티 라이브러리에 대한 의존이었다.Java 16에 record가 들어왔다. public record Point(double x, double y) {} — 한 줄. 컴파일러가 나머지를 다 만들어 준다. (JEP-395) 왜 Java는 30년이나 지나서야 이 한 줄을 가능하게 했을까? 이 글은 record, sealed, enum 세 가지 현대 타입이 기존 코드를 어떻게 바꾸..