왜 pk인 userId를 받을 때 Long wrapper class로 받냐고 성능이 안좋다고 피드백 받았다.
그래서 정리하려고 쓰는글 ~
Java에서 primitive type과 wrapper class는 서로 다른 개념입니다.
Primitive type은 Java에서 기본적으로 제공되는 8가지 데이터 타입(byte, short, int, long, float, double, boolean, char)을 말합니다. 이들은 메모리에 값을 직접 저장하며, 산술 연산 등이 빠르고 효율적으로 처리됩니다.
Wrapper class는 primitive type의 값을 객체로 다룰 수 있게끔 해주는 클래스입니다. Wrapper class는 8가지 primitive type 각각에 해당하는 클래스(Byte, Short, Integer, Long, Float, Double, Boolean, Character)를 제공합니다. Wrapper class는 primitive type의 값에 대한 객체 지향적인 기능을 제공합니다. 예를 들어, primitive type은 null 값을 가질 수 없지만, Wrapper class는 null 값을 가질 수 있습니다.
또한, primitive type과 Wrapper class 간의 자동 변환(auto-boxing, unboxing)이 가능합니다. 이것은 Java 5부터 추가된 기능으로, primitive type을 Wrapper class로 자동으로 변환하거나, Wrapper class를 primitive type으로 자동 변환할 수 있습니다. 예를 들어, Integer wrapper class의 인스턴스를 int primitive type 변수에 대입할 때, 자동으로 unboxing이 수행됩니다.
따라서, primitive type은 값을 직접 저장하므로 메모리 사용이 적고 처리 속도가 빠르지만, 객체 지향적인 기능을 제공하지 않습니다. 반면에 Wrapper class는 객체 지향적인 기능을 제공하지만, primitive type에 비해 메모리 사용이 더 많고 처리 속도가 느릴 수 있습니다.
Spring Boot에서 pk를 Long인 wrapper 대신 long인 primitive로 하는 것이 더 좋은 이유는 성능과 메모리 사용 측면에서 발생합니다.
Long 클래스는 객체이기 때문에 인스턴스화되어야 하며, 그렇기 때문에 기본 자료형인 long에 비해 메모리 사용량이 더 많아집니다. 또한 Long 객체는 불변 객체이므로 값을 변경할 수 없으며, 값을 변경하려면 새로운 Long 객체를 생성해야 합니다. 이에 따라 불필요한 객체 생성과 가비지 컬렉션을 유발하여 애플리케이션의 성능을 저하시키는 원인이 됩니다.
반면에 long 기본 자료형은 값 자체를 저장할 수 있기 때문에 객체 인스턴스화를 할 필요가 없으며, 메모리 사용량이 적습니다. 또한 long 변수는 값을 변경할 수 있으므로 불필요한 객체 생성과 가비지 컬렉션을 방지할 수 있습니다.
따라서 Spring Boot에서 pk를 long 기본 자료형으로 사용하는 것이 더 효율적입니다. 하지만 이는 모든 상황에서 일반적으로 적용되는 규칙은 아니며, 경우에 따라 Long wrapper 클래스를 사용하는 것이 더 적절할 수도 있습니다. 예를 들어 pk가 null일 수 있는 경우나, 기본값이 아닌 다른 값(예: -1)을 사용해야 하는 경우 등이 그렇습니다.