java8이 들어오고 나서 Optional 이라는 개념이 등장하게 되었습니다. Optional에 대해서 알아보기에 앞서 Optional이 등장하게 된 배경에 대해 얘기해보겠습니다.
웹, 앱 애플리케이션을 개발하거나 알고리즘 문제를 풀 때 종종 NPE(NullPoinerException)이라는 오류를 종종 보게됩니다. 이는 실제 값이 아닌 null을 가지고 있는 객체 혹은 변수를 호출할 때 발생하는 예외입니다.
다음과 같은 코드가 있을 때 NullPointerException이 발생하게 됩니다.
package me.whiteship.java8to11;
public class Practice {
public static void main(String[] args) {
Integer id = null;
String str_id = id.toString();
System.out.println(str_id);
}
}
NullPointerException이 발새하는 코드
이외에도 다양한 상황에서 NullPointerException이 발생하는 상황이 종종 나타나고 이를 해결하는 방법에는 크게 3가지가 있습니다.
💡 Try Catch 문 이용
위의 코드를 Try Catch문을 이용해 해결하면 다음과 같습니다.
package me.whiteship.java8to11;
public class Practice {
public static void main(String[] args) {
Integer id = null;
try{
String str_id = id.toString();
System.out.println(str_id);
} catch (NullPointerException e){
id = 111111;
String str_id = id.toString();
System.out.println(str_id);
} finally{
System.out.println("항상 실행");
}
}
}
위의 코드의 경우 성공과 실패의 코드가 모두 드러나며 변수 하나의 상황에서도 여려줄의 코드들이 작성되는데 더 복잡한 상황(여려개의 변수가 null 경우 혹은 객체가 null인 경우)에서는 개발자가 감당하기가 어려울 것입니다.
💡 if문 활용
위의 코드를 if문을 활용해서 해결하면 다음과 같습니다.
package me.whiteship.java8to11;
public class Practice {
public static void main(String[] args) {
Integer id = null;
if(id == null){
System.out.println("id가 null입니다");
}else{
String str_id = id.toString();
System.out.println(str_id);
}
}
}
if문 역시 변수 하나에 대해서 null인지 아닌지를 판단하는 코드 역시 여러줄이 나타나게 되며 더 복잡한 상황(여려개의 변수가 null 경우 혹은 객체가 null인 경우)에서는 비효율적인 코드가 만들어지는 경우가 생길 것입니다.
위와 같이 null로 인해 발생하는 비효율적인 코드를 제거하기 위해 Optional이라는 개념이 등장하게 되었습니다.
Optional이란 NPE(NullPointerException)을 방지하기 위해 NPE가 발생할 수 있는 변수나 객체들에 대해 Option 클래스로 감싸주는 Wrapper 클리스입니다. Optional에 경우 값이 들어있을 수 도 있고 값이 들어있지 않을 수 있는 컨테이너 입니다.
Optional의 경우 static method인 empty(), of(), ofNullable()을 통해 Optional 객체를 생성할 수 있습니다. of()의 경우 매개변수 값이 null인 경우에 NPE가 발생할 수 있기에 null 가능성이 있는 경우에는 ofNullable()을 사용해야합니다.
package me.whiteship.java8to11;
import java.util.Optional;
public class Practice {
public static void main(String[] args) {
Optional<Integer> id = Optional.empty();
System.out.println(id.isPresent()); //false를 반환
}
}
empty를 통해 Optional을 생성하면 값이 없는 것을 알 수 있습니다. isPresent()는 값이 null인 경우에는 false를 반환하며 있는 경우에는 true를 반환해주는 메소드입니다.
package me.whiteship.java8to11;
import java.util.Optional;
public class Practice {
public static void main(String[] args) {
Optional<Integer> id = Optional.of(1234);
System.out.println(id.isPresent());
}
}
of() 경우 무조건 값을 인자로 받아야하면 없는 경우에는 NPE가 발생하게 됩니다.
package me.whiteship.java8to11;
import java.util.Optional;
public class Practice {
private static Integer student_id;
public static Integer getStudent_id() {
return student_id;
}
public void setStudent_id(Integer student_id) {
this.student_id = student_id;
}
public static void main(String[] args) {
Optional<Integer> id = Optional.ofNullable(getStudent_id());
System.out.println(id.orElse(1234));
}
}
ofNullable()의 경우에는 null이 올수도 있고 아닌 경우도 있습니다. 그렇기에 orElse()를 활용해 값이 null인 경우에는 사용자가 지정한 default값을 가져올 수 있습니다.
이제 맨 위에서 발생한 NPE를 Optional를 활용해 해결하면 다음과 같습니다.
💡 Optional를 통해 해결
package me.whiteship.java8to11;
import java.util.Optional;
public class Practice {
public static void main(String[] args) {
Optional<Integer> id = Optional.ofNullable(null);
String str_id = id.orElse(111111).toString();
System.out.println(str_id);
}
}