Java7 부터 Objects.requireNonNull() 메소드가 있어 더 이상 null 검사를 수동으로 하지 않아도 된다.
//생성자
public ClassName(Long id, Long fromMemberId, Long toMemberId, LocalDateTime createAt) {
this.id = id;
this.fromMemberId = Objects.requireNonNull(fromMemberId) ;
this.toMemberId = Objects.requireNonNull(toMemberId);
this.createAt = Objects.requireNonNullElse(createAt, LocalDateTime.now());
}
Object.requireNonNull() : 반드시 not null 이어야 하는 경우 (java 1.8 지원)
- null이면 NullPointException 발생
- 사용 예)
- this.fromMemberId = Objects.requireNonNull(fromMemberId) ;
- this.fromMemberId = Objects.requireNonNull(fromMemberId, "fromMemberId에 값이 없습니다.") ;
Object.requireNonNullElse(객체, default) : null 일 경우 기본 값 리턴 (java 1.9 지원)
- 사용 예)
- this.createAt = Objects.requireNonNullElse(createAt, LocalDateTime.now());
- Java 1.8까지는 아래와 같이 코딩
- this.createAt = createAt == null ? LocalDateTime.now() : createAt;
public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)
- 객체가 null이면, 람다식 결과를 리턴
- 실행 시기 결정 가능 - Lazy Evaluation
- 앞의 파라미터가 null인 경우에만 람다식을 실행하기 때문에 requireNonNullElse의 default에 메소드 리턴값을 넣는 것보다 성능이 빠르다.
- requireNonNullElse 는 성능에 영향이 거의 없는 경우 사용
- Object 생성 또는 메소드 호출로 인한 성능 지연을 줄이고 싶은 경우 requireNonNullElseGet 을 사용
this.direction = Objects.requireNonNullElseGet(direction, () -> System.getProperty(“com.direction.default”))
this.modulemdApi = Objects.requireNonNullElseGet(modulemdApiIn, ModulemdApi::new);
this.color = Objects.requireNonNullElseGet(color, () -> new Color(0, 0, 0));
service = Objects.requireNonNullElseGet(val, () -> "rmi://localhost:" + Registry.REGISTRY_PORT + "/" +
ReflectionHelper.getClassBaseName(this.getClass()));
Supplier<String> defaultMemberName = () -> "홍길동";
this.memberName = Objects.requireNonNullElseGet(memberName, defaultMemberName);
Test Case 작성 예
class A {
private final String x;
public A(String x) {
this.x = x;
}
public String getX() {
return x;
}
}
//Test Java
public class ATests {
private A createNonNullA() {
return new A("x");
}
private A createNullA() {
return null;
}
@DisplayName("requireNonNull - not null 일때 통과한다.")
@Test
void testRequireNonNull1() {
A a = createNonNullA();
Objects.requireNonNull(a);
assertDoesNotThrow(() -> (Objects.requireNonNull(a)));
}
@DisplayName("requireNonNull - null 일때 빈 메시지의 NPE 를 던진다.")
@Test
void testRequireNonNull2() {
A a = createNullA();
assertThrows(NullPointerException.class,
() -> Objects.requireNonNull(a));
}
@DisplayName("requireNonNull - null 일때 2번 매개변수 메시지의 NPE 를 던진다.")
@Test
void testRequireNonNull3() {
A a = createNullA();
Exception exception = assertThrows(NullPointerException.class,
() -> Objects.requireNonNull(a, "For input A instance"));
String expectedMessage = "For input A instance";
String actualMessage = exception.getMessage();
assertTrue(actualMessage.contains(expectedMessage));
}
@DisplayName("requireNonNull - null 일때 Supplier<String> 메시지를 NPE 에 담아 를 던진다.")
@Test
void testRequireNonNull4() {
A a = createNullA();
Exception exception = assertThrows(NullPointerException.class,
() -> Objects.requireNonNull(a, () -> ("hello")));
String expectedMessage = "hello";
String actualMessage = exception.getMessage();
assertTrue(actualMessage.contains(expectedMessage));
}
@DisplayName("requireNonNullElse - 둘 다 not null 일때 1번 매개변수를 리턴한다.")
@Test
void testRequireNonNullElse1() {
A a1 = new A("x");
A a2 = new A("y");
A actualA = Objects.requireNonNullElse(a1, a2);
assertEquals(a1, actualA);
}
@DisplayName("requireNonNullElse - 1번 매개변수가 null 일때 2번 매개변수를 리턴한다.")
@Test
void testRequireNonNullElse2() {
A a1 = createNullA();
A a2 = new A("y");
A actualA = Objects.requireNonNullElse(a1, a2);
assertEquals(a2, actualA);
}
@DisplayName("requireNonNullElse - 둘 다 null 일때 NPE 를 던진다.")
@Test
void testRequireNonNullElse3() {
A a1 = createNullA();
A a2 = createNullA();
assertThrows(NullPointerException.class,
() -> Objects.requireNonNullElse(a1, a2));
}
@DisplayName("requireNonNullElseGet - 1번 매개변수가 null이면 Supplier 를 리턴한다.")
@Test
void testRequireNonNullElseGet() {
String expected = "x";
String actual = Objects.requireNonNullElseGet(null, () -> "x");
assertEquals(expected, actual);
}
// ----------------------------------------------------------------
@DisplayName("checkIndex - 0 <= index < length 일때 index 반환한다.")
@Test
void testCheckIndex1() {
int index = 4;
int length = 5;
assertEquals(index, Objects.checkIndex(index, length));
}
@DisplayName("checkIndex - index >= length 일때 IndexOutOfBoundsException 던진다.")
@Test
void testCheckIndex2() {
int index = 5;
int length = 3;
assertThrows(IndexOutOfBoundsException.class,
() -> Objects.checkIndex(index, length));
}
@DisplayName("checkFromToIndex - from ~ to 가 0 ~ length 사이에 있으면 fromIndex 를 리턴한다.")
@Test
void testCheckFromToIndex1() {
int fromIndex = 0;
int toIndex = 3;
int length = 3;
assertEquals(fromIndex, Objects.checkFromToIndex(fromIndex, toIndex, length));
}
@DisplayName("checkFromToIndex - from ~ to 가 0 ~ length 사이에 없으면 IndexOutOfBoundsException 를 던진다.")
@Test
void testCheckFromToIndex2() {
int fromIndex = 0;
int toIndex = 5;
int length = 3;
assertThrows(IndexOutOfBoundsException.class,
() -> Objects.checkFromToIndex(fromIndex, toIndex, length));
}
@DisplayName("checkFromIndexSize - from ~ from+size 가 0~length 사이에 있으면 from을 리턴한다.")
@Test
void checkFromIndexSize1() {
int length = 5;
assertEquals(3, Objects.checkFromIndexSize(3, 2, length));
}
@DisplayName("checkFromIndexSize - from ~ from+size가 0~length 사이에 없으면 IndexOutOfBoundsException 를 던진다.")
@Test
void checkFromIndexSize2() {
int length = 5;
assertThrows(IndexOutOfBoundsException.class,
() -> Objects.checkFromIndexSize(3, 3, length));
}
}
추가 참고 Java 8의 Optional
https://blog.naver.com/ghdalswl77/222892924327
Objects.requireNonNullElse VS Optional
Objects.requireNonNullElse(Obj, null);
==> NullPointException 발생
Optional.ofNullable(nullStr).orElse(null);
==> null
jshell> Optional.ofNullable(nullStr).orElseGet(() -> null);
==> null
String str = null;
String result = str == null ? "other string" : str;
//or
result = Objects.requireNonNullOrElse(str,"other string);
//or
result = Optional.ofNullable(str).orElse("other string");
'프로그래밍 > Java-Spring' 카테고리의 다른 글
Java 함수형 프로그래밍 (0) | 2023.01.17 |
---|---|
Java 8 함수형 인터페이스 (Functional Interface) (0) | 2023.01.11 |
5. 와일드카드 타입 <?>, <? extends ...> <? super ...> (0) | 2023.01.11 |
@RequiredArgsConstructor 를 이용한 의존성 주입 (0) | 2022.12.14 |
Multi SpringApplication 을 선택 처리하는 방법 (0) | 2021.02.26 |