Optional 개념
실제로 개발을 하면서 많이 발생하는 예외 중 하나는 NPE(NullPointerException)입니다. NPE를 예외 처리 하기 위해서는 null 여부를 확인해야 하는 처리가 많이 들어가게 되는데 그러한 경우에는 코드가 복잡하거나 지저분해 질 수 있습니다. 그래서 Java 8에서는 Optional 클래스를 사용해 NPE를 방지할 수 있도록 도와줍니다.
Optional 클래스는 Integer나 Double 클래스처럼 'T' 타입의 객체를 포장해 주는 래퍼 클래스(Wrapper class)입니다. Optional 객체를 사용하면 예상치 못한 NullPointerException 예외를 제공되는 메소드로 간단히 회피할 수 있습니다.
즉, 복잡한 조건문 없이도 null 값으로 인해 발생하는 예외를 처리할 수 있게 됩니다.
Optional 생성
Optional 객체는 of(), ofNullable()를 사용하여 생성할 수 있습니다.
of() 메소드
of() 메소드는 null이 아닌 명시된 값을 가지는 Optional 객체를 반환합니다. 만약 of() 메소드를 통해 생성된 Optional 객체에 null이 저장되면 NullPointerException 예외가 발생합니다.
// value 값이 Null이면 NullPointerException 예외가 발생한다.
Optional<String> opt = Optional.of(value);
ofNullable() 메소드
ofNullable() 메소드는 명시된 값이 null이 아니면 명시된 값을 가지는 Optional 객체를 반환하며, 명시된 값이 null이면 비어있는 Optional 객체를 반환합니다.
// value 값이 Null이면 Optional.empty()가 리턴된다.
Optional<String> opt = Optional.ofNullable(value);
Optional 중간처리
Optional 객체를 가져와서 어떤 처리를 하고 다시 Optional 객체를 반환할 수 있습니다.
filter() 메소드
filter() 메소드의 인자로 받은 람다식이 참이면, Optional 객체를 그대로 반환하고 거짓이면 Optional.empty()를 반환합니다.
Optional<String> opStr1 = Optional.of("ABC");
Optional<String> opStr2 = Optional.of("DEF");
Optional<String> filtered1 = opStr1.filter(s -> s.contains("A"));
Optional<String> filtered2 = opStr2.filter(s -> s.contains("A"));
// 출력 : ABC
filtered1.ifPresent((s) -> System.out.println(s));
// 출력 X
filtered2.ifPresent((s) -> System.out.println(s));
Optional 접근
get() 메소드
Optional 객체에 저장된 값을 바로 가져오는 메소드이며 그 값이 null이면 NoSuchElementException 예외가 발생합니다.
Optional<String> opt = Optional.ofNullable("ABC");
//출력 : ABC
System.out.println(opt.get());
isPresent() 메소드
Optional 객체에 저장된 값이 있다면 true를 리턴하고 값이 null이면 false를 리턴합니다.
Optional<String> opt = Optional.ofNullable("ABC");
if(opt.isPresent()) {
//출력 : ABC
System.out.println(opt.get());
}
ifPresent() 메소드
isPresent() 메소드는 일반적인 자바 스타일로 구현되었습니다. Optinal은 Optional.ifPresent(Consumer)라는 함수형 인터페이스를 인자로 받는 함수도 제공합니다.
Optional.ifPresent(Consumer)는 Optional의 객체가 null이 아닐 때 인자로 전달된 Consumer 함수를 호출하고, 객체가 null이라면 아무것도 하지 않습니다.
String nullString = null;
Optional<String> opString = Optional.of("ABC");
Optional<String> nullOpString = Optional.ofNullable(nullString);
// 출력 : opString : ABC
opString.ifPresent(s -> System.out.println("opString: " + s));
// 출력 X
nullOpString.ifPresent(s -> System.out.println("nullOpString: " + s));
orElse() 메소드
Optional.orElse(object)는 Optional이 갖고 있는 객체가 null이 아닐 때 객체를 리턴하며, null이면 인자로 전달된 object가 리턴됩니다.
String nullString = null;
Optional<String> opString = Optional.of("ABC");
Optional<String> nullOpString = Optional.ofNullable(nullString);
String str = opString.orElse("DEF");
// 출력 : ABC
System.out.println(str);
String str2 = nullOpString.orElse("DEF");
// 출력 : DEF
System.out.println(str2);
orElseGet() 메소드
Optional.orElseGet(Supplier)는 Optional의 객체가 null이 아니면 리턴하고, null이면 인자로 전달된 함수를 실행시킵니다.
Supplier는 인자가 없고 리턴 값이 있는 함수형 인터페이스로, 람다 표현식으로 구현할 수 있습니다.
String nullString = null;
Optional<String> opString = Optional.of("ABC");
Optional<String> nullOpString = Optional.ofNullable(nullString);
String str3 = opString.orElseGet(() -> "DEF");
// 출력 : ABC
System.out.println(str3);
String str4 = nullOpString.orElseGet(() -> "DEF);
// 출력 : DEF
System.out.println(str4);
orElseThrow() 메소드
Optional.orElseGet(Supplier)는 Optional의 객체가 null이 아니면 리턴하고, null이면 예외를 발생시킵니다.
String nullString = null;
Optional<String> opString = Optional.of("ABC");
Optional<String> nullOpString = Optional.ofNullable(nullString);
// 출력 : ABC
try {
String str = opString.orElseThrow(NullPointerException::new);
System.out.println(str);
}
catch (NullPointerException e) {
System.out.println("NullPointerException");
}
// 출력 : NullPointerException
try {
String str = nullOpString.orElseThrow(NullPointerException::new);
System.out.println(str);
}
catch (NullPointerException e) {
System.out.println("NullPointerException");
}
'프로그래밍 언어 > Java' 카테고리의 다른 글
equals() (0) | 2025.02.16 |
---|---|
System.out.print (0) | 2025.02.16 |
동기&비동기, 블로킹&논블로킹 (0) | 2025.02.16 |
Garbage Collection(GC) (0) | 2025.02.16 |
Comparable, Comparator (0) | 2025.02.16 |