개발을 하면서 자주 격게되는 exception 중에 하나인NullPointerException 이라는 예외처리를 항상 예상하고 처리해야 된다. 거기서 Optional을 쓰면 null을 예외처치를 쉽게 할 수 있다.
Optional을 쓰지 않으면 if로 예외 처리를 해줘야하는데 코드가 길어지고 가독성도 떨어지는 단점이 있다.
예를 들어
public class Info {
private String phone; // null일 수도 있음
private String name; // null일 수도 있음
private Integer age; // null일 수도 있음
public Info(String phone, String name, Integer age) {
this.phone = phone;
this.name = name;
this.age = age;
}
public String getPhone() {
return this.phone;
}
public String getName() {
return this.name;
}
public Integer getAge() {
return this.age;
}
}
public class Test {
public static void main(String[] args) {
Info info = new Info("010-1234-1234", "Han", null);
System.out.println(info.getPhone()); // 010-1234-1234
System.out.println(info.getName()); // Han
System.out.println(info.getAge()); // NullPointerException!
}
}
그러면 오류를 방지하기 위해서 이런씩으로 해야할까?
if (null == info.getPhone()) {
// ...
System.out.println("phone null!")
}
if (null == info.getName()) {
// ...
System.out.println("name null!")
}
if (null == info.getAge()) {
// ...
System.out.println("age null!")
}
System.out.println(info.getPhone());
System.out.println(info.getName());
System.out.println(info.getAge());
이런씩으로 하나씩 처리하기 위해 if 문을 쓰니 좀 어려워진다.
이렇게 Null 생길 수 있는 멤버들은 하나하나 if 문을 써서 검사해줘야 되고 가독성도 떨어지고 화살표 모양이 되고 있다.
이럴때 쓰라고 따로 만들어 놓은것이 Optional이다.
public final class Optional<T> extends Object {
private final T value; // 이 참조 변수를 통해 저장
}
Optinal<String> A = Optinal.of(new String("Test1");
Optinal<String> B = Optinal.ofNullable(new String("Test1");
of과 ofNullable의 차이점
null의 허용하는지에 대한 차이점이다. ofNullable은 Null을 전달할 수 있다. of은 Null을 허용하지 않는다. Null을 전달하면 NullPointerException이 발생한다.
isPresent
isPresent을 통해 내용물을 꺼낼 수 도 있다.
// 람다
A.ifPresent(s -> System.out.println(s));
// 메소드 참조
B.ifPresent(System.out::println);
// if
if (os1.isPresent()) {
System.our.println(os1.get());
}
isPresent는 내용물이 있으면 true을 반환하고 없으면 false을 반환한다.
반면 내용물이 없으면 아무 일도 일어나지 않는다.
class OptionalMap {
public static void main(String[] args) {
Optional<String> A = Optional.of("Optional String");
Optional<String> B = os1.map(s -> s.toUpperCase());
System.out.println(os2.get());
Optional<String> C = os1.map(s -> s.replace(' ', '_'))
.map(s -> s.toLowerCase());
System.out.println(os3.get());
}
}
진행 되는 순서
Optional String -> Optional_String -> optional_string
// empty()을 사용하면 내용이 없는 값인 Optional을 반환한다.
Optional<String> A = Optional.empty();
// of는 값이 없으면 NullPointerException을 일으킴
Optional<String> B = Optional.of("Hi");
String s1 = A.map(s -> s.toString()).orElse("Empty");
String s2 = B.map(s -> s.toString()).orElse("Empty");
System.out.println(s1);
System.out.println(s2);
결과
Empty
Hi
이상 글을 마치겠다.
너무 쉽게 작성해주셔서 감사합니다