Optional을 알기 위해선 NullPointerException을 알아야 한다 !
모든 개발자들이 무서워하는 에러 중 하나인 NullPointerException.....
직역하면 알수있는데, 말 그대로 Null값을 참조하기에 예외를 발생시킨것이다 !
아래 코드와 같이 Null일수 있는 데이터가 있다면, 해당 값을 애초에 초기화를 시켜놓거나 Null인지 아닌지 검사를 해줘야 한다.
public void nullException(){
String name = "";
name = makeName(name); // 메소드를 통해 값을 초기화 했지만 Null일수 있다.
name.equals("Java"); // Null값을 가지고 문자열과 비교를 하기에 예외가 발생한다.
}
public void notNull(){
String name = "Java";
name = makeName(name); // name이라는 변수는 값이 있기에 다시 본인의 이름으로 값이 초기화 된다.
name.equals("Java");
}
public String makeName(String name){ // 테스트를 위해 고의로 NUll값을 넘겼다.
if(name.equals("")){
return name;
}
return null;
}
Optional은 이러한 Null 참조 예외를 쉽게 처리하기 위해 등장했습니다 :)
Optional은 null이 될 수 있는 값을 감싸는 Wrapper클래스로 참조하더라도 예외 발생을 막아줍니다.
세가지 메소드를 통해 인스턴스 생성이 가능하며, 만약에 값이 비어있을 경우 비어있는
Optional객체를 return함으로써 null이 아니게 되는겁니다.
자 그러면 어떻게 써야 하는지 알아봐야겠죠 허헣.
// Null상태로 생성되는 Optional
Optional<String> optionalEmpty = Optional.empty();
// Null이면 명시된 값을 가지는 Optional - 메소드 및 파라미터가 올 수 있다.
Optional<String> optionalNotEmpty = Optional.ofNullable(makeName("woojin"));
// Null이면 명시된 값을 가지는 Optional - 메소드 및 파라미터가 올 수 있다.
Optional<String> optionalNeverEmpty = Optional.of("비어있으면 안댕");
- empty() 메소드 : 비어있는 Optional 객체를 생성한다.
- ofNullable() 메소드 : Null일 경우 명시된 값을 가지고 초기화 한다.
- of() 메소드 : Null일 경우 명시된 값을 가지고 초기화 한다.
?? ofNullable이랑 of가 똑같은거 아니에요 ??
중요한 차이점이 존재 합니다!
ofNullable()은 명시된 값이 null이여도 예외를 발생시키지 않습니다. 즉 말 그대로 Nullable하다는 뜻입니다.
of()는 명시된 값이 null이면 여전히 NullPointerException을 일으킵니다.
ofNullable() - null값을 가지게 되도 상관없다
public String makeName(String name){
if(!name.equals("")){
return name;
}
return null;
}
// 메소드의 결과값이 Null을 반환하지만 NullPointerException이 발생하지 않는다.
Optional<String> optionalNotEmpty = Optional.ofNullable(makeName(""));
of() - null값을 가지게 되면 예외 발생
public String makeName(String name){
if(!name.equals("")){
return name;
}
return null;
}
// 결과값이 null이기에 NullPointerException을 발생시킨다.
Optional<String> optionalNeverEmpty = Optional.of(makeName(""));
orElse(), orElseGet() 의 사용법 & 차이점
둘 다 값이 비어있지 않을 경우에 어떤 행동을 취할지 명시하는 메소드입니다.
orElse() -> 직접적으로 값을 전달합니다.
orElseGet() -> 메소드 자체를 전달합니다.
이 둘의 차이점은 생각보다 매우 중요합니다. 코드와 함께 보시죠 !
@Test
void testElseGet(){
// orElseGet 사용시 함수가 넘어간다. 즉 함수는 있지만 null값이 아니라면 실행되지 않는다.
String o = Optional.ofNullable("Java").orElseGet(this::areYouIn);
}
@Test
void testElse(){
// orElse 사용시 값이 넘어간다. 즉 함수가 바로 실행이 되고 결과값을 가지고 있는 상태이다.
// null유무와 상관없이 함수가 실행되고 그 결과값을 null유무에 따라 넘길지 말지 정한다.
String o = Optional.ofNullable("Java").orElse(areYouIn());
}
public String areYouIn(){
System.out.print("메소드에 들어왔어요!");
return "Pyton";
1. orElse() -> 값을 넘긴다.
public void testElse(){
String o = Optional.ofNullable("Java").orElse(areYouIn());
}
public String areYouIn(){
System.out.print("메소드에 들어왔어요!");
return "Python";
}
ofNullable("Java")가 있기에 orElse()는 실행이 안되는것 같지만, 앞서 말했듯이 값을 넘겨주기 때문에, 메소드의 실행 결과를 가지고 대기중인 상태다 ! 그리고 나서 null 유무에 따라 값을 초기화 하는것 입니다.
2. orElseGet() -> Method를 넘긴다.
void testElseGet(){
String o = Optional.ofNullable("Java").orElseGet(this::areYouIn);
}
public String areYouIn(){
System.out.print("메소드에 들어왔어요!");
return "Python";
}
메소드 자체를 넘기기에 null 유무에 따라서 함수 자체를 실행시킬지 말지 결정을 합니다. 그렇기에 orElse()와는 다르게 함수를 실행 시키지 않는것을 확인할 수 있습니다.
if문 쓰면 되는거 아닌가?
if를 이용하여 null값을 체크하고 대처할 수 있습니다.
하지만 if를 이용하여 null값을 체크하면 안좋은 이유가 있기에 등장했겠죠?
첫번째. 코드가 쓸모없이 길어진다 -> 가독성이 떨어진다
두번째. 각각의 변수마다 null값을 체크해야되는데 개발자의 실수로 인해 놓칠수 있다
Optional is intended to provide a limited mechanism for library method return types where there needed to be a clear way to represent “no result," and using null for such was overwhelmingly likely to cause errors.
- Brian Goetz(Java Architect) - Java 언어 설계자
대략 해석해보자면 :
Optional은 반환 타입으로 사용하도록 의도하여 설계하였다는 내용입니다. 무차별적인 Optional 사용은 성능을 저하시킬수 있으며 예측할 수 없는 결과가 발생한다고 경고를 하고 있습니다.
그래서 반환 타입으로만 사용하는걸 적극 권장하고 있습니다 !
오늘도 모두 슬기로운 코딩 생활 하십쇼!!
잘못 기재된 사실이나 부족한 부분은 피드백 주시면 감사하겠습니다 :)
더불어 궁금한 내용에 대해 댓글을 남겨주시면 답변해드리도록 하겠습니다 .
'Java' 카테고리의 다른 글
[Java] POJO (Plain Old Java Object) 란? feat. 코드로 알아보자! (1) | 2023.03.18 |
---|---|
[Java] Enum 이란? 왜 사용할까? - 장점들 (2) | 2023.03.13 |
InnerClass 왜 사용할까? (0) | 2023.01.13 |
Java Collection ApI 핵심 정리 (0) | 2023.01.13 |
윤년과 평년을 구별하는 프로그래밍 (0) | 2023.01.13 |