2 분 소요

📖 원시 타입(Primitive Type)

실제 값만을 저장하는 공간으로 스택 메모리 영역에 저장된다. 기본 값이 존재하기 때문에 null 값을 활용하고 싶다면 wrapper class를 활용해야한다.

  타입 크기 default
논리형 boolean 1 byte false
정수형 byte 1 byte 0
  short 2 byte 0
  int 4 byte 0
  long 8 byte 0L
실수형 float 4 byte 0.0F
  double 8 byte 0.0
문자형 char 2 byte ‘\u0000’

char 타입의 기본값은 널 문자로 참조형 변수인 널 값과는 다르니 헷갈리지 말자.

📖 참조 타입(Reference Type)

스택에 저장되어 있는 실제 값의 주소 값이 저장되는 타입으로 힙 메모리 영역에 저장된다.

  기본값 할당되는 메모리 크기
Array null 4 byte
Enum null 4 byte
Class null 4 byte
Interface null 4 byte

⚠️ 참조 타입이라고 해서 call by reference 방식인 것은 아니다.

자바에서는 call by reference가 없다. 자바에서는 매개변수로 값을 넘길 때 변수 자체를 참조하는 것이 아니라 변수가 가리키는 주소를 복사해서 사용하기 때문에, 객체의 멤버 변수를 변경하면 해당 주소의 값이 바뀌어버리므로 변경이 적용되지만, 매개변수에 다른 객체 자체를 할당해봤자 전달한 인자의 참조는 변하지 않는다.

📖 Wrapper Class

Primitive Type의 데이터를 서로 형 변환이 가능하도록 지원해주는 클래스로써, 원시 타입의 자료형들을 클래스화한 것이다.

Primitive Type Wrapper Class
int Integer
byte Byte
char Character
double Double
float Float
long Long
short Short

📝 래퍼 클래스(wrapper class) 사용 이유

  1. 매개변수로 객체가 요구될 때

  2. 기본형 값이 아닌 객체로 저장해야 할 때

  3. 객체 간 비교가 필요할 때

  4. 형 변환이 자유롭다

📝 박싱(Boxing) & 언박싱(UnBoxing)

wrapper.png

📝 오토 박싱(AutoBoxing) & 오토 언박싱(AutoUnBoxing)

Integer num = new Integer(17); // 박싱
int n = num.intValue();        // 언박싱
Character ch = 'X';            // 오토박싱
char c = ch;                   // 오토언박싱

📝 Wrapper 클래스의 값 비교

  • 래퍼클래스 == 기본타입 : true

    auto unboxing 발생으로 기본타입끼리 계산

  • 래퍼클래스.equals(기본타입) : true
  • 래퍼클래스 == 래퍼클래스 : false

    안에 든 값은 같아도 두 객체는 엄연히 다르다.

  • 래퍼클래스.equals(래퍼클래스) : true
int value = 10; 
Integer wrapper_value = new Integer(value); 
Integer wrapper_value2 = new Integer(value); 
System.out.println(wrapper_value == wrapper_value2); // false
System.out.println(wrapper_value.equals(wrapper_value)); // true

이렇게 선언을 하려고 해봤는데 9버전부터는 저런 식으로 박싱을 해주지 않는다고 한다…

Wrapper 클래스에서는 정적 팩토리 메서드를 제공해주는데, 이를 활용하여 인스턴스를 선언해주면 다음과 같다.

int value = 10; 
Integer wrapper_value = Integer.valueOf(value); 
Integer wrapper_value2 = Integer.valueOf(value); 
System.out.println(wrapper_value == wrapper_value2); // true
System.out.println(wrapper_value.equals(wrapper_value)); // true

이렇게 정적 팩토리 메서드를 활용하면 미리 캐싱한 인스턴스를 리턴하기 때문에 일정 범위의 값에 대해서는 동일 객체를 반환한다. 따라서 ==로 비교해도 true가 리턴되는 것을 볼 수 있다.

📝 정적 팩토리 메서드(Static Factory Method)

정적 팩토리 메서드는 클래스의 인스턴스를 반환하는 정적 메서드를 의미한다.

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

다음은 Integer 클래스의 정적 팩토리 메서드 예시로, 정적 팩토리 메서드의 장점은 다음과 같이 볼 수 있다.

  1. 이름을 가질 수 있다.

    생성자는 단순히 해당 클래스의 이름을 갖는데, 정적 팩토리 메서드를 사용해주면 그 이외의 이름을 가지기 때문에 동작의 의도를 더 잘 명시해준다.

  2. 호출할 때마다 인스턴스를 새로 생성하지 않아도 된다.

    위의 코드와 같이 일정 범위의 값을 캐싱해놓음으로써 클래스의 필드값이나 구성요소를 변경할 수 없는 불변클래스 구현이 가능하다.

참고


https://limdingdong.tistory.com/16

댓글남기기