[F-Lab 모각코 챌린지] 59일차 - Request dto 에서 int 가 아닌 Integer 를 사용한 이유

F-Lab 모각코 챌린지 59일차. int 가 아닌 integer 를 사용하는 이유를 정리해보았습니다.

[F-Lab 모각코 챌린지] 59일차 - Request dto 에서 int 가 아닌 Integer 를 사용한 이유
검증되지 않은 값은 신뢰하지 않는다.

기본적으로 int 형은 null 을 저장할 수 없다. 사용자가 null 을 입력하면 빨간 줄을 띄우며 에러가 발생한다

하지만 프론트에서 직렬화 되어 날아오는 json 데이터는 다르다

null 이 들어오게 되면 0 으로 바꿔서 저장하게 되는데 이 문제가 크게 작용할 수 있다

예를 들어...

  • 프론트에서 중요한 id 값이 필수로 들어와야 한다
  • DB 에서 null 형태의 값을 리턴 할 수 있다
  • 숫자 형태로 데이터가 들어와야 한다

이런 경우, primitive 타입의 int 를 사용하게 되면 null 이 들어왔음에도 동작은 정상적으로 수행될 수 있다

결과적으로 익셉션을 발생시키지 않는 해당 문제를 파악하는 시간이 오래 걸릴 수 있게 된다

하지만 Integer 를 사용하게 된다면 null 을 사용하는 순간 서비스가 익셉션을 발생시킬 수 있기 때문에 디버깅이 더 쉬워지고 문제 해결이 빨라진다

주의 할 점

IntegerLong 을 사용할 때 주의해야 할 점

  • equals 로 비교해야 한다
  • null 이 들어갈 수 있음을 염두해 두어야 한다

equals 로 비교해야 한다

예제 1

다음의 코드를 보자

int intValueA = 1;
int intValueB = 1;

Integer integerValueA = 1;
Integer integerValueB = 1;

System.out.println("intValue == intValueB : " + (intValueA==intValueB));
System.out.println("integerValueA == integerValueB : " + (integerValueA==integerValueB));
System.out.println("====================================");

long longValueA = 1L;
long longValueB = 1L;

Long LongValueA = 1L;
Long LongValueB = 1L;

System.out.println("longValueA == longValueB : " + (longValueA == longValueB));
System.out.println("LongValueA == LongValueB : " + (LongValueA == LongValueB));

실행 결과는 다음과 같다

위의 결과를 보고 의아 했다면 당신은 클래스를 충분히 이해하고 있는 것이고, 만약 "당연하지" 라고 생각했다면 JVM 의 정수형 동작 방식을 충분히 이해하고 있는 사람일 것이다

예제 2

그럼 다음 코드를 보자

int intValueA = 128;
int intValueB = 128;

Integer integerValueA = 128;
Integer integerValueB = 128;

System.out.println("intValue == intValueB : " + (intValueA==intValueB));
System.out.println("integerValueA == integerValueB : " + (integerValueA==integerValueB));
System.out.println("====================================");

long longValueA = 128L;
long longValueB = 128L;

Long LongValueA = 128L;
Long LongValueB = 128L;

System.out.println("longValueA == longValueB : " + (longValueA == longValueB));
System.out.println("LongValueA == LongValueB : " + (LongValueA == LongValueB));

위 코드의 결과는 무엇일까?

정답은 primitive type 은 true 이고 Class 타입은 false 이다

왜 저렇게 동작할까?

JVM 은 정수 데이터를 다룰 때 0 ~ 127 사이의 숫자는 최적화를 위해 자동으로 캐싱된다

따라서 Integer 는 0 ~ 127 범위의 값은 같은 레퍼런스를 참조하기 때문에 == 비교 시 같은 레퍼런스를 바라보게 되고, 이 때문에 true 라는 값이 나오게 된다

그 이외의 숫자는 다른 레퍼런스에 생성되기 때문에 false 가 나오는 것이고...

스크린샷 아래부분을 보자

integerValueAintegerValueB 는 둘 다 {Integer@829}0 으로, 같은 레퍼런스를 가지고 있지만

_integerValueA_integerValueB 는 각각 {Integer@830}128, {Integer@831}128 으로, 다른 레퍼런스를 가지고 있는 것을 확인할 수 있다

결과적으로!

Integer integerValueA = 128;
Integer integerValueB = 128;

System.out.println(integerValueA == integerValueB);      // 이게 아니라
System.out.println(integerValueA.equals(integerValueB)); // 이렇게 사용해야 한다