ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • primitive type vs wrapper class
    JAVA 2021. 10. 31. 00:49

    Java 에서는 8가지 Primitive Data type 을 제공 합니다.

    그리고 Primitive Type에 대한 Wrapper Class 를 제공하는데요.

    여기에 대한 차이에 대해서 한번 알아봅시다! 

    그리고 어떤 경우에 primitive Type을 써야 하고 Wrapper Class 를 사용해야 하는지 알아봐요! 😀

     

    Primitive Type과 Wrapper Class에 대한 Default Value 확인 (Sample Code)

    public class Main {
    
        byte primitiveTypeByte;
        short primitiveTypeShort;
        int primitiveTypeInt;
        long primitiveTypeLong;
        float primitiveTypeFloat;
        double primitiveTypeDouble;
        char primitiveTypeChar;
        boolean primitiveTypeBoolean;
    
        Byte wrapperByte;
        Short wrapperShort;
        Integer wrapperInteger;
        Long wrapperLong;
        Float wrapperFloat;
        Double wrapperDouble;
        Character wrapperCharacter;
        Boolean wrapperBoolean;
        String wrapperString;
    
        public static void main(String[] args) {
    
            final Main main = new Main();
    
            System.out.println(">>>>>>>>>> Default Values to Primitive Type");
    
            System.out.println("byte : " + main.primitiveTypeByte);
            System.out.println("short : " + main.primitiveTypeShort);
            System.out.println("int : " + main.primitiveTypeInt);
            System.out.println("long : " + main.primitiveTypeLong);
            System.out.println("float : " + main.primitiveTypeFloat);
            System.out.println("double : " + main.primitiveTypeDouble);
            System.out.println("char : " + main.primitiveTypeChar);
            System.out.println("boolean : " + main.primitiveTypeBoolean);
    
            System.out.println(">>>>>>>>>> Default Values to Wrapper Class");
    
            System.out.println("Byte : " + main.wrapperByte);
            System.out.println("Short : " + main.wrapperShort);
            System.out.println("Integer : " + main.wrapperInteger);
            System.out.println("Long : " + main.wrapperLong);
            System.out.println("Float : " + main.wrapperFloat);
            System.out.println("Double : " + main.wrapperDouble);
            System.out.println("Character : " + main.wrapperCharacter);
            System.out.println("Boolean : " + main.wrapperBoolean);
            System.out.println("String : " + main.wrapperString);
        }
    }

     

    Primitive Type과 Wrapper Class에 대한 Default Value 확인 (Output)

    >>>>>>>>>>Default Values to Primitive Type
    byte : 0
    short : 0
    int : 0
    long : 0
    float : 0.0
    double : 0.0
    char : '\u0000'
    boolean : false
    >>>>>>>>>>Default Values to Wrapper Class of Primitive  Type
    Byte : null
    Short : null
    Integer : null
    Long : null
    Float : null
    Double : null
    Character : null
    Boolean : null
    String : null

     

    Default Value 의 차이

    primitive 에는 초기화 해주지 않아도 기본 값을 가지고 있습니다.

    하지만 Wrapper Class의 경우는 초기화를 해주지 않으면 null 을 기본 값으로 가지고 있는 걸 확인할 수 있어요! :)

    또한 API Docs 에 가서 보면 해당 Primitive Type 의 Wrapper Class에는 모두(Byte, Short, Integer, Long, Float, Double, Boolean, Character) value-based class 라는 간략한 메모가 포함되어 있습니다.

    더보기

    This is a value-based class; programmers should treat instances that are equal as interchangeable and should not use instances for synchronization, or unpredictable behavior may occur. For example, in a future release, synchronization may fail.

    * 참고: value-based class 에는 primitive type의 wrapper class 외에도 java.time 패키지의 Instant, LocalDate, LocalTime.. 등 도 있습니다.

     

    그러면 value-based claas란 무엇일까요?

    아쉽게도 제가 분명하게 이해하지 못했기 때문에 정확한 전달은 어려울 것 같지만 여러 문서와 블로깅 한 결과를 조금이나마 요약해서 알려 드리고 싶네요 :)

    Java API Docs 도 읽어보고 여러 문서도 참조해 봤지만, 문서에서 말하는 이유들이 와닿지는 않았습니다.

    하지만 대략적인 내용을 정리해 보면 다음과 같습니다.

    - optional과 관련이 있고 functional programming 으로 진화하기 위함

    - final 이어야 하고 immutable(불변) 이어야 함

    - 값을 비교할 때 (==) 비교가 아닌 equals() 로 비교해야 함

    - equals(), toString(), hashCode() 를 갖고 있어야 함

    - 값 비교 시에 id로 값을 비교해서는 안됨

    자세한 내용에 대해서 궁금하다면 openjdk 문서에 있는 jep390, oracle jdk 문서에 있는 value-base class 문서를 읽어보면 좋을 것 같습니다.

    그리고 여러 타 블로그에서는 해당 문서에 대한 내용을 풀어서 설명하고 있으니 검색해 보면 도움이 될 수도 있을 것 같습니다.

     

    가장 궁금한 것. Primitive Type 을 써야 할까요. Primitive Type을 Wrapping 한 클래스를 써야 할까요?

    중요하게 생각하는 부분에 따라 상황에 맞게 사용하면 되는데요. 특정 상황에서 유용한 선택에 대해 정리해 봤습니다.

     

    Memory : primitive

    Java JVM의 종류는 다양합니다. JVM 별로 조금씩 메모리 할당량은 다릅니다.. 하지만 분명한 것은

    int 와 Integer를 메모리 비교했을 때 int가 훨씬 적은 메모리를 차지합니다.

    메모리만 신경 쓴다면 Integer 보다는 primitive type 인 int를 사용해야 합니다.

    일반적으로...

    • int : 32bit
    • Integer : 128bit

     

    Performance : primitive

    그리고 또 성능의 문제도 있습니다.

    JVM 메모리 구조에 int와 Integer는 각기 다른 공간에 저장됩니다.

    primitive 타입은 stack에 있고 reference 타입은 heap 에 위치 합니다.

    아래 bealdung 사이트를 참고했습니다. 실제 성능 테스트를 제가 한건 아니지만 해당 블로그 작성을 위해 bealdung 사이트를 벤치마킹했으니 참고해 주시면 감사하겠습니다.

     

    Generic : Wrapper

    Java 에서는 Generic Type으로 primitive type을 사용하는 것을 허용하지 않습니다.

    Generic Type을 써서 value-base class를 사용해야 하는 경우에는 Wrapper 클래스를 사용해야 합니다.

     

    비즈니스 및 도메인에 대한 상황에 따라 : primitive, Wrapper

    절대 null일 수 없는 경우가 있다면 primitive 타입을 써야 하고

    null 이 가능해야 하는 경우라면 반드시 Wrapper 클래스를 사용해야 할 수 있습니다.

    null로 들어가야 하는 게 맞는데 의도치 않게 0을 기본값으로 갖게 될 경우가 생길 수도 있고

    비어있을 수도 있습니다.

    Entity를 설계한 의도에 따라 primitive 타입 또는 Wrapper를 선택할 수 있습니다.

     

    Casting, 유연함, 다양한 지원 기능 : Wrapper

    아무래도 primitive 타입은 값만 담을 수 있지만, Wrapper 클래스는 말 그대로 클래스이기 때문에 다양한 메서드가 구현되어 있어 여러 가지 유연하고 편리한 기능들이 사용 가능합니다.

    WrapperClass가 가진 기능들을 다양하게 사용해야 하는 경우라면 primitive 타입보다는 Wrapper 타입을 사용하는 게 좋습니다.

     

    결론

    성능과 메모리만 생각한다면 primitive 타입을 써야 합니다.

    하지만, 클래스의 구조(Collection), 유연하고 다양한 기능이 필요할 때면 Wrapper Class를 써야 합니다.

    도메인 및 비즈니스 모델 설계에 따라서는 상황에 맞게 primitive Type 또는 Wrapper 클래스를 써야 합니다.

    결과적으로는 어떤 상황이냐에 따라 선택할 수밖에 없다고 보일 수 있겠는데요.

    하지만 저희가 만들고 있는 시스템은 항상 시간이 지나면 지날수록 거대해지기 마련입니다.

    그렇다면 필요하지 않은 곳에는 Wrapper 클래스를 사용하지 않는 편이 좋을 것 같습니다.

    아무 의미 없이 모든 필드에 primitive 타입 없이 전부 Wrapper 클래스를 사용하는 것은 좋지 않다고 보입니다.

     

    최종 정리! 항상 primitive 타입을 기본적으로 사용하되, 필요한 경우에 따라 Wrapper 클래스를 사용해 주는 게 Bestpractice이지 않을까 정리해 봅니다.😀

     

    reference

    댓글

Designed by Tistory.