Java Optional 사용법

Jang990·2023년 2월 2일
0

22년 09월 03일에 작성된 글

Optional

Optional 객체 생성

/*
str(100번지) -> "abc"(100번지 값)
optVal(200번지) -> 100번지 주소(200번지 값) -> "abc"(100번지 값)
이렇게 참조하고 있다.
*/
String str = "abc"
Optional<String> optVal = Optional.of(str);

Optional<String> optVal2 = Optional.of(null); // 널포인터 익셉션 오류 발생 Null을 다루기 위해 Optional을 쓰기때문에 이건 잘 안씀
Optional<String> optVal3 = Optional.ofNullable(null); // 오류 안남
Optional<String> optVal = null; // 바람직하지 않음
Optional<String> optVal = Optional.empty(); // 빈 객체로 초기화

Optional객체 값 가져오기

Optional<String> optVal = Optional.of("abc");
String str1 = optVal.get(); // optVal에 저장된 값 반환. null이면 예외 발생

//이 아래것들을 자주 씀
String str2 = optVal.orElse(""); // optVal에 저장된 값이 null이면 ""를 반환
String str3 = optVal.orElseGet(String::new); // 람다식 사용가능, optVal에 저장된 값이 null이면 new String()를 반환
String str4 = optVal.orElseThrow(NullPointerException::new); //널이면 예외 발생
//orElse와 orElseGet은 같은 것 같지만 다르다. 차이는 아래서 설명한다.

Optional에서 사용하는 map()Stream과 똑같이 사용하면 된다.


내용출처: https://www.youtube.com/watch?v=W_kPjiTF9RI



Optional.orElse() VS Optional.orElseGet()

orElse()는 null과 상관없이 항상 불립니다. orElseGet()은 null일 때만 불린다. 다음 예시를 통해 위험한 상황을 확인하자.

public User findByUsername(String name) {
	return userRepository.findByName(name).orElse(createUserWithName(name));
}

private User createUserWithName(String name) {
	User newUser = new User();
	newUser.setName(name)
	return userRepository.save(user);
}

위의 상황은 orElse()로 인해 createUserWithName() 메소드가 User가 null이든 말든 실행된다. 그러므로 항상 User가 생성되는 상황이다. 만약 name이 unique였다면 장애가 발생하는 상황이다.

즉 위 코드는 아래코드와 같다.

public User findByUsername(String name) {
	User newUser = createUserWithName(name); // 무조건 User를 생성해서 DB에 저장
	return userRepository.findByName(name).orElse(newUser);
}

private User createUserWithName(String name) {
	User newUser = new User();
	newUser.setName(name)
	return userRepository.save(user);
}

차이를 이해하고 있자


내용 출처: https://cfdf.tistory.com/34

profile
공부한 내용을 적지 말고 이해한 내용을 설명하자

0개의 댓글