Null
널
값이 없음을 나타내는 특별한 값. NullPointerException의 원인이며 Tony Hoare의 "Billion Dollar Mistake"로 불리는 프로그래밍 개념.
널
값이 없음을 나타내는 특별한 값. NullPointerException의 원인이며 Tony Hoare의 "Billion Dollar Mistake"로 불리는 프로그래밍 개념.
Null은 프로그래밍에서 "값이 없음(absence of value)"을 나타내는 특수한 값입니다. 변수가 어떤 객체도 참조하지 않거나, 아직 초기화되지 않았거나, 의도적으로 비어있음을 표현할 때 사용됩니다. 데이터베이스에서는 "알 수 없는 값"이나 "적용 불가능한 값"을 표현하는 데 사용되며, 0이나 빈 문자열("")과는 명확히 다른 의미를 가집니다.
Null 참조(Null Reference)는 컴퓨터 과학자 Tony Hoare가 1965년 ALGOL W 언어를 설계하면서 도입했습니다. 그는 2009년 QCon 컨퍼런스에서 이를 "Billion Dollar Mistake(10억 달러짜리 실수)"라고 불렀습니다. null 참조로 인해 지난 40년간 발생한 수많은 버그, 보안 취약점, 시스템 충돌이 최소 10억 달러의 비용을 유발했다는 의미입니다.
JavaScript에서는 null과 undefined라는 두 가지 "값이 없음"을 나타내는 값이 존재합니다. null은 개발자가 의도적으로 "값이 없음"을 할당한 경우를 나타내며, undefined는 변수가 선언되었지만 아직 값이 할당되지 않은 상태를 나타냅니다. 이 두 값은 == 비교에서는 같지만 === 비교에서는 다릅니다.
현대 프로그래밍 언어들은 Null Safety(널 안전성)를 위한 다양한 접근 방식을 제공합니다. Java 8+의 Optional, Kotlin의 Nullable Types(?), Swift의 Optional, Rust의 Option 등이 대표적입니다. 이들은 컴파일 타임에 null 가능성을 명시하고, null을 다룰 때 안전한 방법을 강제함으로써 런타임 NullPointerException을 방지합니다.
// 1. 전통적인 null 체크 public String getUserName(User user) { if (user != null) { if (user.getName() != null) { return user.getName(); } } return "Anonymous"; } // 2. Optional 사용 (Java 8+) public String getUserNameSafe(User user) { return Optional.ofNullable(user) .map(User::getName) .orElse("Anonymous"); } // 3. Objects.requireNonNull - 방어적 프로그래밍 public void processUser(User user) { Objects.requireNonNull(user, "User must not be null"); // user가 null이면 NullPointerException 발생 }
// null vs undefined 비교 let a; // undefined (선언만 함) let b = null; // null (의도적으로 비움) console.log(a == b); // true (느슨한 비교) console.log(a === b); // false (엄격한 비교) // Optional Chaining (?.) - ES2020 const userName = user?.profile?.name ?? "Anonymous"; // Nullish Coalescing (??) - null/undefined만 처리 const count = inputCount ?? 0; // 0이나 ""는 그대로 사용 const count2 = inputCount || 0; // 0이나 ""도 0으로 대체
// Kotlin의 Nullable Types var name: String = "John" // null 불가 var nullableName: String? = null // null 가능 // Safe call operator (?.) val length = nullableName?.length // null이면 null 반환 // Elvis operator (?:) val len = nullableName?.length ?: 0 // null이면 0 // Not-null assertion (!!) - 권장하지 않음 val forceLength = nullableName!!.length // NPE 발생 가능 // let을 이용한 null 체크 nullableName?.let { println("Name length: ${it.length}") }
user.getAddress().getCity() 부분이 위험해 보이네요. user나 address가 null일 수 있는 상황에서 NullPointerException이 발생할 수 있습니다. 어떻게 수정하면 좋을까요?
Optional을 사용해서 Optional.ofNullable(user).map(User::getAddress).map(Address::getCity).orElse("Unknown")으로 수정하면 될 것 같습니다. 아니면 메서드 시작 부분에서 Objects.requireNonNull로 빨리 실패하도록 할 수도 있을 것 같은데요.
String?처럼 nullable을 명시하고 컴파일러가 강제합니다. Rust는 null 자체가 없고 Option<T>로 값의 존재 여부를 표현해요. Java는 Optional을 도입했지만 기존 코드와의 호환성 때문에 강제는 못 하고 있습니다.
requireNonNull로 빠르게 실패시킵니다. 셋째, 필드는 생성자에서 초기화하여 null 상태를 최소화합니다.
Optional.get()을 직접 호출하는 것도 피하세요.NULL = NULL은 false입니다. IS NULL, COALESCE, NULLIF 함수를 적절히 사용하세요.