Skip to content

지식 공유 | ObjectUtils.isEmpty와 StringUtils.hasText의 차이

Zinzo edited this page Jun 2, 2025 · 1 revision

저는 주로 객체가 비어 있거나, 문자열이 비어 있음 확인을 ObjectUtils.isEmpty로 체크 해 왔었습니다.
평소와 같이 해당 로직을 작성하고, 동아리 프로젝트에 PR을 올렸는데 다음과 같은 코멘트를 받게 되었습니다.

image

과거 StringUtils.isEmptyObjectUtils.isEmpty 차이점에 대한 글 작성 후,
값 체크는 그냥 ObjectUtils.isEmpty를 쓰기로 했던게 습관처럼 지금까찌 이어 졌었습니다.

그러다 이번 리뷰를 계기로, StringUtils.hasText의 경우 어떠한 차이점이 있는지 찾아보게 되었습니다.

StringUtils.hasText의 역할은?

StringUtilsSpring Framework에서 제공해주는 유틸리티 클래스입니다. hasText의 경우,

  • 문자열이 null이 아니며
  • 길이는 0보다 크고
  • 공백만으로 이루어져 있지 않음 , 실제로 의미 있는 텍스트로 이루어져 있는지 확인하는 용도로 사용됩니다.

ObjectUtils.isEmpty는?

ObjectUtils.isEmpty()null이나 비어 있는 객체를 판별하는 범용 메서드입니다.
대상은 String, Collection, Map, 배열 등 다양한 타입이며, 단순히 객체의 ‘비어 있음’만 체크합니다.

두 메서드의 차이점

입력 값을 바탕으로 두 메서드는 어떠한 차이점이 있는지 정리 하였습니다.

입력 값 StringUtils.hasText ObjectUtils.isEmpty
null false true
"" false true
" " false false
"abc" true false
  • " " (빈 공백 문자열)는 hasText()에서는 비어 있음, isEmpty()에서는 비어 있지 않음으로 처리됩니다.
  • 이 차이점이, 유효성 검증에 있어서 의도하지 않은 검증 처리가 될 수 있기에 명확한 차이를 알아야 합니다.

ObjectUtils.isEmpty 테스트코드

@Test  
@DisplayName("ObjectUtils.isEmpty 테스트")  
void testObjectUtilsIsEmpty() {  
    assertThat(ObjectUtils.isEmpty(null)).isTrue();  
    assertThat(ObjectUtils.isEmpty("")).isTrue();   
    assertThat(ObjectUtils.isEmpty(" ")).isFalse();  
    assertThat(ObjectUtils.isEmpty("text")).isFalse();  
  
    assertThat(ObjectUtils.isEmpty(new ArrayList<>())).isTrue();  
    assertThat(ObjectUtils.isEmpty(Arrays.asList("value"))).isFalse();  
  
    assertThat(ObjectUtils.isEmpty(new HashMap<>())).isTrue();  
    assertThat(ObjectUtils.isEmpty(Map.of("key", "value"))).isFalse();  
  
    assertThat(ObjectUtils.isEmpty(new int[]{})).isTrue();  
    assertThat(ObjectUtils.isEmpty(new int[]{1, 2})).isFalse();  
}

""는 비어 있다고 판단하지만, " "는 비어있지 않다고 판단하는 것을 확인할 수 있습니다.

StringUtils.hasText 테스트코드

@Test  
@DisplayName("StringUtils.hasText 테스트")  
void testStringUtilsHasText() {  
    assertThat(StringUtils.hasText(null)).isFalse();  
    assertThat(StringUtils.hasText("")).isFalse();  
    assertThat(StringUtils.hasText(" ")).isFalse();  
    assertThat(StringUtils.hasText("text")).isTrue();  
}

null, 빈 문자열, 공백 문자열 모두 의미 있는 텍스트가 없다고 판단합니다.

두 메서드 차이

@Test  
@DisplayName("두 유틸 메서드 차이 비교")  
void compareObjectUtilsAndStringUtils() {  
    final String str = " ";  
    assertThat(ObjectUtils.isEmpty(str)).isFalse();    // 공백은 '비어있지 않다'  
    assertThat(StringUtils.hasText(str)).isFalse();    // 공백은 '의미 있는 텍스트가 없다'  
  
    final String nonEmptyStr = "hello";  
    assertThat(ObjectUtils.isEmpty(nonEmptyStr)).isFalse();  
    assertThat(StringUtils.hasText(nonEmptyStr)).isTrue();  
}

결론

StringUtils.hasText()는 null 여부까지 함께 검사하기 때문에, NPE 방지용으로도 유용하게 활용할 수 있습니다.
또한, 입력값으로 " "(공백 문자열)도 허용할 것인지에 따라 선택 기준이 달라집니다.

  • 공백 문자열도 허용하는 정책이라면 : ObjectUtils.isEmpty() 사용
  • 의미 있는 텍스트만 허용해야 한다면 : StringUtils.hasText() 사용

그리고 ObjectUtils는 모든 객체(Object)를 대상으로 하는 범용 유틸 클래스이기 때문에,
단순히 문자열 유효성만 검사하고자 한다면 StringUtils를 사용하는 것이 더 명확한 의도를 전달할 수 있습니다.

최종적으로 변경된 코드

public void modify(final String title, final String content) {|
   if (StringUtils.hasText(title)) {
     this.title = title;
   }

   if (StringUtils.hasText(content)) {
     this.content = content;
   }
}

소감

그동안 객체가 비어 있지 않음을 표현할 때는 !ObjectUtils.isEmpty() 형태로 사용하는 경우가 많았는데,
이 방식은 코드를 읽을 때 한 번 더 머릿속으로 부정 의미인 !를 해석해야하는 번거로움을 인지하고는 있었습니다.

반면, StringUtils.hasText()는 이름 자체가 “의미 있는 텍스트가 있는지” 를 직관적으로 표현하고 있어,
개인적으로 훨씬 더 마음에 들었습니다.
앞으로는 이 차이를 명확히 인식하고, 상황에 맞는 메서드를 선택해 코드를 작성하려 합니다.

또한 이번 경험을 통해 코드 리뷰의 중요성을 다시 한 번 느꼈습니다.
혼자 코드를 작성했다면 인지하지 못했을 차이를, 리뷰를 통해 빠르게 발견하고 개선할 수 있었던 점이 매우 만족스러운 것 같습니다. 👍🏻

도움을 주신 지원님께 감사드립니다~!

Clone this wiki locally