본문 바로가기

JAVA/Effective Java

item 61) 박싱된 기본 타입보다 기본 타입을 사용하라

728x90

자바 데이터 타입  :

1) 기본 타입 int, double, boolean ...)

2) 참조타입(String, List , 사용자 정의 클래스 ...)

 

- 각각의 기본 타입마다 대응하는 참조 타입을 가지고 있으며 이를 박싱된 기본 타입이라고 한다.

int -> Integer, double -> Double,  boolean -> Boolean

 

- 오토 박싱, 오토 언박싱으로 두 타입을 구분하지 않고 사용할수 있다.

ex) Integer a = 42; (42가 오토박싱된다.

기본 타입 vs 박싱 타입

 

- 기본타입은 값만 가지고 있으나, 박싱된 기본타입은 식별성을 가지고 있다. 값이 같더라도 다르다고 판별할수 있다. (Object의 하위 클래스다.)

- 박싱된 기본타입은 null 값을 가질수 있다.

- 기본타입이 박싱된 기본타입보다 시간, 메모리 사용면에서 더 효율적이다.(연산할때 오토 언박싱, 오토박싱이 이뤄지기 떄문)

 

Comparator<Integer> naturalOrder = (i, j) -> (i < j) ? -1 : (i == j ? 0 : 1);

naturalOrder.compare(new Integer(42), new Integer(42)); // false(값이 같아도 다르다고 판별한다.)
public class Unbelievable {
    static Integer i;
    
    public static void main(String[] args) {
        if (i == 42) {
            System.out.println("믿을 수 없군"); // i를 오토 언박싱하는 과정에서 NullPointerException 발생
        }else{
        	System.out.println("??");
        }
    }
}
public static void main(String[] args) {
    Long sum = 0L;
    for (long i = 0L; i < Integer.MAX_VALUE; i++) {
        sum += i; //sum -> Auto Unboxing -> +=연산후 Auto Boxing 과정이 약 2억번 발생한다.
    }
    System.out.println(sum);
}

 

박싱 타입로 반드시 써야만 하는경우

 

- 자바에서는 매개변수화된 메서드, 타입)제네릭 매개변수로 기본 타입을 지원하지 않는다.)

ex) Collection<int> X -> Collection<Integer>

 

- 리플렉션을 통해 메서드를 호출하는 경우

 

코틀린의 기본 타입(Primitive Type)

 

- 코틀린의 모든 타입은 참조 타입으로 멤버 함수와 속성을 변수에 호출할 수 있음

- 다만, 예외가 있는데 기본 타입의 경우 유저에게는 일반 클래스처럼 보일 수 있지만, 코틀린 코드가 Jvm Byte code로 변환되는 시점에서 윈시 값으로 변환된다. 다만 제네릭처럼 반드시 박싱타입을 사용해야할 경우에는 박싱타입을 사용한다!

- 그러므로 위의 자바 코드처럼 사용자가 실수하는 것을 컴파일 타임에 방지할수 있다.

 

List<Integer> numbers = new ArrayList<>();

numbers.add(0); // <-- you use primitive, but in fact, JVM will convert this primitive to object.
numbers.add(new Integer(0)); // <-- We don't need do that.


Kotlin doesn't have primitive type (I mean you cannot declare primitive directly). It uses classes like Int, Float as an object wrapper for primitives.

When kotlin code is converted to jvm code, whenever possible, "primitive object" is converted to java primitive. In some cases this cannot be done. Those cases are, for example, collection of "primitives". For example, List<Int> cannot contains primitive. So, compiler knows when it can convert object to primitive. And, again, it's very similar to java:

 

 

stackoverflow.com/questions/57408327/does-kotlin-have-primitive-types