본문 바로가기
  • 오늘도 한걸음. 수고많았어요.^^
  • 조금씩 꾸준히 오래 가자.ㅎ
IT기술/JAVA

[Java] null 에 대한 검증, 처리방법

by 미노드 2024. 1. 14.

문자열에 대해 복습하면서, null에 대해 한번쯤 정리를 해보고 싶었습니다.

예전에 만들어 둔 소스들을 프로젝트에만 저장해서 뒀는데, 블로그에 한번 공유하는 것도 좋을 것 같았습니다.

null이라는 형식은 아무것도 없는 것을 의미합니다.
이는 빈값을 참조하는 것과 다른 의미로, 참조하는 것이 없다는 의미입니다.
그렇다고 해서 초기화 하지 않은 int a; 이런게 null이라는 것은 아닙니다.
null이라는 형식이 존재하며, 이것 자체로 아무것도 없는 것을 의미합니다.

중요한 것은 기본형 변수나 참조 변수가 null로 들어갔을 때, 특정 메소드 처리중에 런타임 에러를 발생시키는 것입니다.
이는 컴파일러로 걸러지는 부분이 아니어서 테스트를 통해 검증하지 않으면, 문제가 발생할 확률이 높습니다.
그래서 null이 들어갔을때 어느부분에서 에러가 발생하는지, 실험하는 소스를 만들어봤습니다.

String참조변수에 null이 들어갈 때, isEmpty()로 검증하면, 에러가 발생합니다.
그러나 컴파일러에서 걸러지지 않는 unchecked 에러입니다.
이를 에러처리시키기 위해 try catch를 두르는게 꼭 답은 아닐것입니다.

String sn= null; 일 경우
sn.equals(null) 이방법도 NullPointerException 에러가 발생하며,
sn.isEmpty()  이방법도 NullPointerException 에러가 발생합니다.
null.equals(sn)  이방법은 불가능 합니다.
"null".equals(sn)   이방법도 null과 "null"은 다르므로 불가능 합니다.

optional을 써서 null일 경우 orElse로 다른 정해진 값을 출력시키던지, ifPresent를 써서 true false로 구분하던지
에러내고싶으면 orElseThrow를 내던지
(sn == null)으로 null일 경우 별도로 처리하던지 같은 방법을 써야할 것 으로 생각됩니다.
String 검증 클래스를 만들어 null 검증 로직을 메소드로 불러와 자주 사용 하기도 했었습니다.

별개로 null != "" 처럼 null과 ""는 다른 부분이지만 빈값이라는 의미는 같기에, 별개로 검증을 해줘야 할지도 모릅니다.
그래서 null을 검증할 때 "" 공백을 같이 검증하기도 했습니다.
이런식으로 null값을 대처하면 좋을 것이라 생각합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class SampleA {
    private String A;
    SampleA() {
        A = null;
    }
    SampleA(String a) {
        A = a;
    }
    public String toString() {
        return A;
    }
}
 
public class ToStringTest {
    public static void main(String[] args) {
        int o;
        int a = 15;
        long l = 16L; // 16도 되긴하지만
        float f = 16.1f;
        double d = 17.2;
        String sa= "hello";
        String se= "";
        String sn= null;
        String s;
        SampleA A = new SampleA();
        //실험1 null 반환시 에러 유무
        System.out.println(A.toString()); // toString() 결과가 null일 경우 null 리턴, System.out.println
//        System.out.println(null)); // System.out.println로 null 출력시 에러발생
        System.out.println((A.toString() == null)); // true, A.toString()은 null
//        System.out.println(A.toString().isEmpty()); // 런타임 에러, A.toString()은 null이며, null.isEmpty() 는 에러 발생
        System.out.println(sn.isEmpty()); // 런타임 에러, sn은 null이며, null.isEmpty() 는 에러 발생, NullPointerException: Cannot invoke "String.isEmpty()" because "sn" is null
        System.out.println(("null".equals(A.toString()))); // false, A.toString()은 "null" 문자열이 아니다.
//        System.out.println((A.toString().equals(null))); // 런타임 에러, NullPointerException: Cannot invoke "String.equals(Object)"
        System.out.println("---------------------");
 
        //실험2 toString, valueOf null 처리 테스트
        String lowerCoatingVal1 = String.valueOf(sn); // valueOf에 null이 들어가면 null로 반환
//        String lowerCoatingVal2 = sn.toString(); // 런타임 에러, null.toString(); 은 에러발생한다.
        System.out.println(lowerCoatingVal1);
//        System.out.println(lowerCoatingVal2);
        System.out.println((lowerCoatingVal1 == null)); // false, lowerCoatingVal1은 null 이 아니다.
        System.out.println(lowerCoatingVal1.isEmpty()); // false, lowerCoatingVal1은 null 이 아니다.
        System.out.println("null".equals(lowerCoatingVal1)); // true, lowerCoatingVal1은 "null" 문자열 이다.
        System.out.println("---------------------");
 
        //실험3 출력 테스트
        System.out.println(sa); // hello 리턴
        System.out.println(se); //     공백 리턴
        System.out.println(sn); // null 리턴
//        System.out.println(s); // 에러
//        System.out.println(String.valueOf(null)); //에러, NullPointerException: Cannot read the array length because "value" is null
        System.out.println(String.valueOf(a)); //
        System.out.println(String.valueOf(l)); //
        System.out.println(String.valueOf(f)); //
        System.out.println(String.valueOf(d)); //
    }
}
cs