A wise man once said you are not a real Java programmer until you've dealt with a null pointer exception. Joking aside, the null reference is the source of many problems because it is often used to denote the absence of a value.
Java SE 8 introduces a new class called java.util.Optional that can alleviate some of these problems.
한 현명한 사람은 널 포인터 예외를 처리하기 전까지는 진정한 Java 프로그래머가 아니라고 말한 적이 있습니다. 농담은 제쳐두고, null 참조는 종종 값의 부재를 나타내는 데 사용되기 때문에 많은 문제의 원인입니다.
Java SE 8에는 이러한 문제 중 일부를 완화할 수 있는 java.util.Optional이라는 새 클래스가 도입되었습니다.
오직 값 한 개가 들어 있을 수도 없을 수도 있는 컨테이너
public class OnlineClass {
private Integer id;
private String title;
private Progress progress;
private boolean closed;
public OnlineClass(Integer id, String title, boolean closed) {
this.id = id;
this.title = title;
this.closed = closed;
}
public Integer getId() {
return id;
}
...
}
public class Progress {
private Duration studyDuration;
private boolean finished;
public Duration getStudyDuration() {
return studyDuration;
}
public void setStudyDuration(Duration studyDuration) {
this.studyDuration = studyDuration;
}
}
public static void main(String[] args) {
/* Java8 이전의 Null을 반환하는 것에 대한 처리
OnlineClass spring_boot = new OnlineClass(1, "spring boot", true);
Progress progress = spring_boot.getProgress();
if(progress != null){
System.out.println(progress.getStudyDuration());
}*/
/* Optional에서 Primitive 타입의 경우
* 내부적으로 Boxing, Unboxing이 발생하기 때문에 권장하지 않는다.
* Primitive 타입용 Optinal을 사용하는게 좋다. */
OptionalInt.of(134);
List<OnlineClass> springClasses = new ArrayList<>();
springClasses.add(new OnlineClass(1, "spring boot", true));
springClasses.add(new OnlineClass(2, "spring data jpa", true));
springClasses.add(new OnlineClass(3, "spring mvc", false));
springClasses.add(new OnlineClass(4, "spring core", false));
springClasses.add(new OnlineClass(5, "rest api development", false));
Optional<OnlineClass> optionalOnlineClass = springClasses.stream()
.filter(x -> x.getTitle().startsWith("spring"))
.findFirst();
OnlineClass getOnlineClass = optionalOnlineClass.get();
System.out.println(getOnlineClass.getTitle());
/*
* Optional한 객체를 가져올 때, 바로 get()을 할 경우 RuntimeException 발생 시킬 수 있다.
* 그러므로, 바로 get() 하지 않고, Null여부에 따른 판단을 해줄 수 있는 메소드를 사용해서 처리하는 것이 좋다.
* */
// 해당 객체가 있으면 어떤 처리를 해줘야 할 때
optionalOnlineClass.ifPresent(x -> System.out.println(x.getTitle()));
// 있으면 객체를 가져오고 없는 경우 해당 객체 타입을 리턴시키는 경우
// orElse 같은 경우 해당 객체가 있던 없던 매개변수를 먼저 실행 시키기 때문에 매개변수에 상수와 같이 이미 선언되어 있는 것을 사용하는 것이 좋다.
OnlineClass onlineClassOrElse = optionalOnlineClass.orElse(createNewClass());
OnlineClass onlineClassOrElseGet = optionalOnlineClass.orElseGet(App::createNewClass);
OnlineClass throwExceptionClass = optionalOnlineClass.orElseThrow(IllegalStateException::new);
Optional<OnlineClass> filteringClass = optionalOnlineClass.filter(OnlineClass::isClosed);
/* flat map */
Optional<Optional<Progress>> optionalOptionalProgress =
optionalOnlineClass.map(OnlineClass::getProgress);
Optional<Progress> optionalProgress = optionalOnlineClass.flatMap(OnlineClass::getProgress);
}
private static OnlineClass createNewClass() {
System.out.println("creating new online class");
return new OnlineClass(10, "New class", false);
}
➕ Optional
➕ Tired of Null Pointer Exceptions? Consider Using Java SE 8's "Optional"!
➕ 이팩티브 자바 3판, 아이템 55 적절한 경우 Optional을 리턴하라.