기본 타입과 참조 타입의 차이

한 줄 정의

Java의 primitive type은 값 자체를 다루는 기본 타입이고, reference type은 객체에 접근하기 위한 참조값을 다루는 타입이다.

실무에서 왜 중요한가

두 타입의 차이를 모르면 ==, equals(), null, wrapper type, 컬렉션 사용에서 버그가 자주 생긴다.

특히 실무에서는 다음 문제가 자주 발생한다.

  • String 값을 ==로 비교한다.
  • Integer, Long 같은 wrapper type을 ==로 비교한다.
  • wrapper type의 null을 고려하지 않아 NullPointerException이 발생한다.
  • Request DTO에서 primitive를 사용해 값 누락과 기본값을 구분하지 못한다.

핵심 개념

  • primitive type은 int, long, double, char, boolean 같은 기본 타입이다.
  • primitive 변수는 실제 값을 가진다.
  • primitive type은 null이 될 수 없다.
  • reference type은 String, 배열, 클래스, 인터페이스, enum 같은 객체 타입이다.
  • reference 변수는 객체 자체가 아니라 객체를 가리키는 참조값을 가진다.
  • reference type은 null이 될 수 있다.

비교 방식

primitive type에서 ==는 값을 비교한다.

int a = 100;
int b = 100;
 
System.out.println(a == b); // true

reference type에서 ==는 같은 객체를 참조하는지 비교한다.

String a = new String("java");
String b = new String("java");
 
System.out.println(a == b);      // false
System.out.println(a.equals(b)); // true

문자열 내용 비교는 ==가 아니라 equals()를 사용한다.

Wrapper Type 주의점

Integer, Long, Boolean 같은 wrapper type은 reference type이다.

따라서 wrapper type은 null이 될 수 있고, 자동 unboxing 과정에서 NullPointerException이 발생할 수 있다.

Integer count = null;
 
if (count == 0) {
    // NullPointerException 발생 가능
}

또한 wrapper type은 reference type이므로 ==로 값 비교를 하면 안 되고, Objects.equals()를 사용하는 것이 안전하다.

Integer a = 128;
Integer b = 128;
 
System.out.println(a == b); // false일 수 있음
System.out.println(Objects.equals(a, b)); // true

실무 판단 기준

  • 값이 반드시 있어야 하면 primitive type을 우선 고려한다.
  • 값이 없을 수 있거나 DB NULL을 표현해야 하면 wrapper type을 사용한다.
  • 객체 내용 비교는 equals()를 사용한다.
  • wrapper type의 값 비교는 Objects.equals()를 사용한다.
  • equals() 호출 대상이 null일 수 있으면 상수나 안전한 객체에서 호출한다.
if ("ACTIVE".equals(status)) {
    // status가 null이어도 안전
}

핵심 요약

Java의 primitive type은 값 자체를 다루는 기본 타입이고, reference type은 객체를 참조하는 타입입니다. primitive type은 null이 될 수 없고 ==로 값을 비교합니다.

반면 reference type은 null이 될 수 있으며, ==는 같은 객체인지 비교하고 equals()는 객체의 의미상 동등성을 비교할 때 사용합니다.

실무에서는 문자열이나 wrapper type을 ==로 비교하거나, wrapper type의 null을 고려하지 않아 NullPointerException이 나는 경우가 많기 때문에 타입 선택과 비교 방식을 명확히 구분해야 합니다.

꼬리 질문

점검 퀴즈

아래 문항은 개념을 실제로 설명할 수 있는지 점검하기 위한 것이다. 선택지를 누르면 정답 여부와 이유가 표시된다.

객관식int 대신 Integer를 선택해야 하는 대표적인 경우는?

OXInteger끼리는 값이 같으면 항상 == 비교가 true다.

객관식Boolean wrapper를 사용할 때 기술 질문에서 자주 지적되는 위험은?

관련 문서