우리는 java 프로그램을 작성하는 도중 남녀노소를 가리지 않고 가장 많이 만나는 오류가 있다. 그것은 NullPointerException이다. 또한 null을 만든 사람도 null이 실수라고 이야기한다. 그럼 우리는 null을 어떻게 회피해야 할까? 이를 이번 장에서 알아볼 것이다.
1.
null 참조의 문제점과 null을 멀리해야하는 이유?
2.
null 대신 Optional : null로 부터 안전한 도메인 모델 재구현하기
3.
Optional 활용 : null 확인 코드 제거하기
4.
Optional에 저장된 값을 확인하는 방법
5.
값이 없을 수도 있는 상황을 고려하는 프로그래밍
null... 우리를 가장 많이 괴롭히는 단어이다. NullPointerException은 어떻게 하더라도 검증이 필요했고 이러한 귀찮은 작업을 필자는 매일매일 프로그램을 작성할때 빼먹지 않는 작업으로 했다. 그렇다면 null은 어떤 상황에서 발생하고 null을 피해야하는 이유는 무엇일까?
null 참조의 문제와 null을 멀리해야 하는 이유
null 이 주는 문제들
•
에러의 근원이다 : 자바에서 가장 흔한 가장 많이 발생하는 에러이다.
•
코드를 어지럽힌다 : 때로는 중첩된 null 확인 코드를 추가해야 하므로 null 때문에 코드의 가독성이 떨어진다.
•
아무 의미가 없다 : null은 아무런 의미도 표현하지 않는다. 특히 정적 형식 언어에서 값이 없음을 표현하는 방법으로는 적절하지 않다.
•
자바 철학에 위배된다 : 자바는 개발자로부터 모든 포인터를 숨겼다. 하지만 그 예외가 null이다.
•
형식 시스템에 구멍을 만든다 : null은 무형식이며 정보를 포함하고 있지 않으므로 모든 참조 형식에 null을 할당할 수 있다. 이런 식으로 null이 할당되기 시작하면서 시스템의 다른 부분으로 null이 퍼졌을 때 애초에 null이 어떤 의미로 사용되었는지 알 수 없다.
null 대신 Optional 클래스
자바는 java.util.Optinal<T> 라는 새로운 클래스를 제공한다. 이는 선택형값을 캡슐화하는 클래스이다. 예를 들자면 어떤 사람이 차를 소유하고 있지 않다면 Person 클래스의 car 변수는 null을 가져야 할 것이다. 하지만 새로운 Optional을 이용할 수 있으므로 null이 할당되는 것이 아니라 변수형을 Optional<Car>로 설정할 수 있다.
값이 있으면 Optional클래스는 값을 감싼다. 하지만 값이 없으면 Optional.empty 메서드로 Optional을 반환한다. Optional.empty는 Optional의 특별한 싱글턴 인스턴스를 반환하는 정적 팩토리 메서드다. null 참조와 Optional.empty()의 차이점은 null을 참조하려 하면 NullPointerException 이 발생하지만 Optional.empty()는 Optional 객체이므로 이를 다양한 방식으로 활용할 수 있다.
값이 없는 상황에서 Optional의 활용 
Opional의 활용과 Optional에서 저장된 값 확인하는 방법
optional 적용 패턴
도메인 모델에 Optional을 사용했을 때 데이터를 직렬화 할 수 없는 이유?
Optional은 "있을 수도 없을 수도" 여부를 구체적으로 표현할 수 있었다. 놀랍게도 Optional 클래스의 설계자는 이와는 다른 용도로만 Optional 클래스를 사용할 것을 가정했다. (Optional의 용도가 선택형 반환값을 지원하는 것 이라고 못박았다.) 즉, Optional 클래스는 필드 형식으로 사용할 것을 가정하지 않았으므로 Serializable 인터페이스를 구현하지 않는다. 따라서 우리 도메인 모델에 Optional을 때려박는다면 직렬화 모델을 사용하는 도구나 프레임워크에 장애가 발생할 수 있다. 이와 같은 단점에도 불구하고 여전히 Optional을 사용해서 도메인 모델을 구성하는 것이 바람직하다고 생각한다.(왜지? 조금 생각해보니 json은 optional을 직렬화할 수 있을까?) 특히 객체 그래프에서 일부 또는 전체 객체가 null 일 수 있는 상황이라면 더더욱 그렇다. 직렬화 모델이 필요하다면 다음과 같이 메서드를 추가하는 방식을 권장한다.
json은 직렬화가 가능할까? https://www.baeldung.com/jackson-optional 가능
class Person{
private Car car;
public Optional<Car> getCarAsOptional(){
return Optional.ofNullable(car);
}
}
Java
복사
기본 보기
Search
값이 없을 수도 있는 상황에서 프로그래밍 방법
지금까지 배운 것처럼 새 Optional 클래스를 효과적으로 이용하려면 잠재적으로 존재하지 않는 값의 처리 방법을 바꿔야한다. 즉, 코드 구현만 바꾸는 것이 아니라 네이티브 자바 API와 상호작용하는 방식으로 바꿔야한다.
결론
•
역사적으로 프로그래밍 언어에서는 null 참조로 값이 없는 상황을 표현해 왔다.
•
자바 8에서는 값이 있거나 없음을 표현할 수 있는 java.util.Optional<T>를 제공한다.
•
Optional은 위의 표에서 알 수 있는 메서드를 이용하여 Optional을 만들 수 있다.
•
Optional 클래스는 Stream에서 제공되는 비슷한 메서드가 존재한다.
•
Optional로 값이 없는 상황을 적절하게 처리하도록 강제할 수 있다. 즉, Optional은 예상치 못한 null을 예외를 방지할 수 있다.
•
Optional 기본 특화형은 안쓰는게 좋다.
•
Optional의 가장 큰 장점은 "있을 수도 없을 수도" 있는 값을 예측할 수 있다.