https://stackoverflow.com/questions/21034955/when-to-use-long-vs-long-in-java
The biggest difference I see between long and Long in this context is that Long may be null. If there's a possibility you might have missing values, the Long object will be helpful as null can indicate missing values. If you're using primitives, you'll have to use some special value to indicate missing, which is probably going to be a mess. Speed or size is not likely to be an issue unless you're planning on making an array of a million of these things and then serializing.
미션을 진행하면서 Request와 Response의 id 데이터 타입이 Long이어서, 아무 생각 없이 다른 레이어의 메서드 내부에서 사용할 때에도 Long을 사용했다. 근데 쓰다보니! 엥? long도 있었던 것 같은데? 라는 생각이 들었다. 어떨 때 Long을 사용하고, 어떨 때 long을 사용해야할까?
먼저, 원시 타입과 참조 타입의 차이점에 대해서 먼저 알아보자.
자바에서는 원시 타입(Primitive Type)과 참조 타입(Reference Type)이 존재한다.
원시 타입은 정수, 실수, 문자, 논리 리터럴 등 실제 데이터 값을 저장하는 타입이고, 참조 타입은 객체의 주소를 저장하는 타입으로 메모리 주소 값을 통해 객체를 참조하는 타입이다.
원시 타입 종류
종류 | 데이터형 | 크기 (byte/bit) | 표현 범위 |
논리형 | boolean | 8 | true/false |
문자형 | char | 16 | \u0000 ~ \uFFFF (16비트 유니코드 문자 데이터) |
정수형 | byte | 8 | -128 ~ 127 |
정수형 | short | 16 | -32768 ~ 32767 |
정수형 | int | 32 | -21억 ~ + 21억 |
정수형 | long | 64 | -9223372036854775808 ~ 9223372036854775807 |
실수형 | float | 32 | |
실수형 | double | 64 |
참조 타입
원시 타입을 제외한 타입(문자열, 배열, 열거, 클래스, 인터페이스)을 말한다. 자바에서 실 객체는 힙 영역에 저장되며, 참조 타입 변수는 스택 영역에 실제 객체들의 주소를 저장하여 객체를 사용할 때마다 참조 변수에 저장된 객체의 주소를 불러와 사용하는 방식이다.
Boxing은 원시 타입을 참조 타입으로 변환시키는 것을 말하고, Unboxing은 참조 타입을 원시 타입으로 변환시키는 것을 말한다.
자바 1.5부터 추가된 Auto Boxing/ Unboxing 기능으로 명시적으로 원시 타입을 참조 타입으로 감싸주지 않아도 자동으로 형변환이 된다. 하지만 이 자동 형변환 기능은 메모리 누수의 원인이 될 수도 있다!
원시 타입과 참조 타입의 차이
1. 원시 타입은 Null을 담을 수 없지만, 참조 타입은 가능한다.
2. 원시 타입은 제너릭 타입에서 사용할 수 없지만, 참조 타입은 가능하다.
3. 원시 타입이 참조 타입보다 메모리양을 덜 사용하므로, 메모리 효율적으로 사용할 수 있다.
4. 참조 타입은 하나의 인스턴스이기 때문에 스택 메모리에는 참조 값만 존재하고, 실제 값은 힙 메모리에 존재한다.
원시 타입은 스택 메모리에 값이 존재한다.
5. 참조 타입은 값을 필요로 할 때마다 언박싱 과정을 거쳐야 하므로 원시 타입과 비교해서 접근 속도가 느려지게 된다.
그럼, Long 보다는 long을 사용하는 것이 더 효율적인 것 같은데..
우선, 웹에서 요청이 들어올 때 사용하는 DTO에는 Long을 명시하는 것이 맞다. 그 이유는 차이 1번에서 말했듯 참조 타입은 null을 받을 수 있기 때문에, missing values를 다룰 때 Long에서 null을 이용할 수 있다. 하지만 이와 같은 경우가 아니라면 모두 long을 사용하는 것이 맞다고 생각한다. 메모리 효율 뿐만 아니라 굳이 불필요한 박싱/언박싱 과정을 거칠 필요가 없기 때문이다!