public final class Optional<T> {
private final T value; //T타입의 참조변수
...
}
1. 래퍼클래스? - 기본 자료타입(primitive type)을 객체로 다루기 위해서 사용하는 클래스 - T타입의 참조변수를 갖고 있음. - Integer, Long 등
2. Optional? Optional도 래퍼클래스인데 제네릭이 T라서 어떤 타입이든지 다 저장이 가능하다. => 모든 종류의 객체 저장 가능 (Null도 가능)
3. Optional 필요한 이유 Optional을 이용하면Null을 간접적으로 처리 가능 ① null을 직접 다루는 것은 위험 => NullPointException발생 가능 ② null을 직접 다루게 되면 null체크를 해야함 -> if문 필수 -> 코드 지저분함.
Object result = getResult(); //반환값은 null or 객체
result.toString();
만약 result가 Null이면 NullPointException이 발생한다. 그래서 처리하는 if문이 들어가야 한다. 즉, result에 Null을 직접 담았다면, Optional객체에 Null을 담는 것이다. 그리고 result에 Optional객체의 주소값을 준다. 그러므로 result값은 항상 Null이 아니게 되는 것이다. 이는 String과 비슷하다.
String str = Null; //사용 X
String str = ""; //빈문자열 사용. new char[0]. 길이가 0인 char배열을 사용하는 것과 같다.
null일 때 예외를 발생할 수 있는 str1과 같은 형식보다는 str2, str3을 많이 쓴다. orElseGet은 람다식을 사용할 수 있다.
T orElseGet(Supplier<? extends T> other)
T orElseThrow(Supplier<? extends X> exceptionSupplier)
str4가 str2,str3과 다른 것은 예외종류를 지정해줄 수 있다.
⚝ isPresent() - Optional객체의 값이 null이면 false, 아니면 true를 반환
if(Optional.ofNullable(str).isPresent()) { // if(str!=null) {
System.out.println(str);
}
// ifPresnt(Consumer) - 널이 아닐때만 작업 수행, 널이면 아무 일도 안 함
Optional.ofNullable(str).ifPresent(System.out::println);
4. OptionalInt, OptionalLong, OptionalDouble
⚝ 기본형 값을 감싸는 래퍼클래스
public final class OptionalInt {
...
private final boolean isPresent; // 값이 저장되어 있으면 true
private final int value; // int타입의 변수
Optional<T>가 있는데 왜 OptionalInt같은 것을 사용할까? 사실 Optional<T>를 사용해도 큰 상관은 없는데 말이다. 바로 성능때문이다. 람다와 스트림이 모든 것을 감싸고 있고, 모든 것을 객체로 다루고 있기 때문에 성능이 떨어진다. 그래서 더 높은 성능이 필요할 때 사용한다. Optional<T>에서 value 타입은 T였는데, OptionalInt에서는 value의 타입이 int이다.
.of(0)을 사용하면 OptionalInt의 value값에 0이 저장된다. .empty()을 사용하면 OptionalInt의 value값에 아무 값도 저장을 안 하는 메소드이다. 하지만 int라서 초기값이 애초에 0이다. 그렇다면 이 둘을 어떻게 구분할 것인가? 그래서 OptionalInt에는 isPresent라는 boolean변수가 존재한다.