백기선(인프런 강의)/더 자바, Java 8
Optional 소개
레알윙
2020. 7. 11. 18:46
반응형
자바 프로그래밍에서 NullPointerException을 종종 보게 되는 이유
- null을 리턴하니까! && null 체크를 깜빡했으니까!
메소드에서 작업 중 특별한 상황에서 값을 제대로 리턴할 수 없는 경우 선택할 수 있는 방법
- 예외를 던진다. (비싸다, 스택트레이스를 찍어두니까.)
- null을 리턴한다. (비용 문제가 없지만 그 코드를 사용하는 클리어인트 코드가 주의해야 한다.)
- (자바 8부터) Optional을 리턴한다. (클라이언트에 코드에게 명시적으로 빈 값일 수도 있다는 걸 알려주고, 빈 값인 경우에 대한 처리를 강제한다.)
Optional
- 오직 값 한 개가 들어있을 수도 없을 수도 있는 컨네이너.
주의할 것
- 리턴값으로만 쓰기를 권장한다. (메소드 매개변수 타입, 맵의 키 타입, 인스턴스 필드 타입으로 쓰지 말자.)
- Optional을 리턴하는 메소드에서 null을 리턴하지 말자.
- 프리미티브 타입용 Optional을 따로 있다. OptionalInt, OptionalLong,...
- Collection, Map, Stream Array, Optional은 Opiontal로 감싸지 말 것.
참고
- https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
- https://www.oracle.com/technical-resources/articles/java/java8-optional.html
- 이팩티브 자바 3판, 아이템 55 적절한 경우 Optional을 리턴하라.
예제
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class AppRun {
public static void main(String[] args) {
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 developement", false));
OnlineClass spring_boot = new OnlineClass(1, "spring boot", true);
// 아래와 같이 코딩을 하게 되면 spring_boot.getProgress가 null이기 때문에
// nullpointException이 발생 된다.
/*Duration studyDuration = spring_boot.getProgress().getStudyDuration();
System.out.println(studyDuration);*/
//위의 오류를 방지하게 위해서는 아래와같이 코드를 작성하면 된다.
Optional<Progress> progress = spring_boot.getProgress();
}
}
public class OnlineClass {
private Integer id;
private String title;
private boolean closed;
public Progress progress;
public OnlineClass(Integer id, String title, boolean closed) {
this.id = id;
this.title = title;
this.closed = closed;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public boolean isClosed() {
return closed;
}
public void setClosed(boolean closed) {
this.closed = closed;
}
public Optional<Progress> getProgress() {
return Optional.ofNullable(progress);
}
public void setProgress(Progress progress) {
this.progress = progress;
}
}
import java.time.Duration;
public class Progress {
private Duration studyDuration;
private boolean finished;
public Duration getStudyDuration() {
return studyDuration;
}
public void setStudyDuration(Duration studyDuration) {
this.studyDuration = studyDuration;
}
}
반응형