Java 8 Optional.
Java/이론..2014. 10. 1. 10:14
Java 8에서 추가된 기능인 Optional에 대해서 간단하게 소개된 글이 있어서 공유 합니다.
(http://java.dzone.com/articles/java-8-optional-avoid-null-and)
언제 어디서나 우리를 괴롭히던 Null 과 NPE를 물리칠 수 있다는 군요! +ㅅ+
참고 : java8-optional
함수형 프로그래밍 : 위키설명
Java 8 Optional - Null 및 NullPointerException 둘다 회피하고 코드를 예쁘게 짜기.
Null 과 NPE(NullPointerException), 이를 회피하는 방법에 대한 문서들을 여러방법으로 소개되고 있다. 이런 방법들 보다 Java 8에서 제공하는 Optinal 기능을 사용하면 쉽고, 안전하고, 아름다운 코드로 작성할 수 있다. 이 문서는 다른 옵션 값들이나 유틸리티코드 사용 없이 이를 구현하는 방법을 소개한다.
이전 방법
아래 코드를 살펴보자
1.
String unsafeTypeDirName = project.getApplicationType().getTypeDirName();
2.
System.out.println(unsafeTypeDirName);
만약 위 코드에서 사용하는 변수들이 null 이면 NPE가 발생된다.
이를 회피 하기 위해서 아래와 같은 코드를 작성했었다.
01.
// 안전하지만 지저분하고 코드가 누락될 수도 있다
02.
if
(project !=
null
) {
03.
ApplicationType applicationType = project.getApplicationType();
04.
if
(applicationType !=
null
) {
05.
String typeDirName = applicationType.getTypeDirName();
06.
if
(typeDirName !=
null
) {
07.
System.out.println(typeDirName);
08.
}
09.
}
10.
}
NPE를 발생 시키지는 않지만 코드가 지저분하고 null 체크가 누락되기 쉽다.
Java 8
Java 8에서 제공하는 Optional 기능을 사용해서 재구현해보자
01.
02.
Optional<Project> optionalProject = Optional.ofNullable(project);
03.
04.
// 안전하고 Java 8을 사용했지만 지저분하고 여전히 코드가 누락될 가능성이 있다
05.
if
(optionalProject.isPresent()) {
06.
ApplicationType applicationType = optionalProject.get().getApplicationType();
07.
Optional<ApplicationType> optionalApplicationType = Optional.ofNullable(applicationType);
08.
if
(optionalApplicationType.isPresent()) {
09.
String typeDirName = optionalApplicationType.get().getTypeDirName();
10.
Optional<String> optionalTypeDirName = Optional.ofNullable(typeDirName);
11.
if
(optionalTypeDirName.isPresent()) {
12.
System.out.println(optionalTypeDirName);
13.
}
14.
}
코드가 늘어나고 더 개선된 내용이 없어 보인다.
Functional Interface를 사용해 Optional의 진짜 힘을 사용해보자!
1.
// 안전하고 깔끔하다
2.
Optional<String> optionalTypeDirName = optionalProject
3.
.map(project -> project.getApplicationType())
4.
.map(applicationType -> applicationType.getTypeDirName());
5.
optionalTypeDirName.ifPresent(typeDirName -> System.out.println(typeDirName));
map()은 한상 Optional 객체를 리턴하기 때문에 Null은 허용되지 않고
IfPresent()는 해당 객체에 값이 있어야 실행되고 기본값 같은것은 전혀 세팅되어 있지 않다.
위 코드를 조금 더 줄여 보면 아래와 같이 작성 할 수있다.
1.
// 안전하고 여전히 깔끔하다
2.
Optional<String> optionalTypeDirName2 = optionalProject
3.
.map(Project::getApplicationType)
4.
.map(ApplicationType::getTypeDirName);
5.
optionalTypeDirName2.ifPresent(System.out::println);
결론
Optional을 사용한다면 null 관련된 작업 및 이를 회피하기 위한 작업을 진행 별도로 하지 않아도 된다.
레거시 코드에서 사용되는 값들이 Null이 될 수 있다면 가능한 빨리 Optional 기능을 사용하길 바란다.