JAVA

Java 변수와 타입 — 이것만 알면 된다 (기본 타입 8가지, var, 타입 추론까지)

IT Lab 2026. 2. 13. 07:34

Java 17 기준으로 기본 타입 8가지와 참조 타입의 차이, var 타입 추론의 정확한 동작, 실무에서 자주 쓰는 타입 선택 기준을 한 번에 정리합니다.

 

코드를 읽다 보면 int는 익숙한데 long을 써야 하는지, double 대신 BigDecimal을 써야 하는지 헷갈릴 때가 많습니다. 또 Java 10+에서 var가 들어오면서 “그냥 다 var로 쓰면 되는 거 아닌가?” 같은 고민도 자주 생깁니다.

핵심 개념: Java 타입을 “정확히” 고르는 기준 (기본 타입 8가지 + var)

primitive 타입과 reference 타입, 그리고 var 타입 추론 흐름을 한 그림으로 요약한 다이어그램

Java의 타입은 크게 기본 타입(primitive)참조 타입(reference) 으로 나뉩니다. 중요한 건 문법보다도 “어떤 선택이 버그와 비용을 줄이느냐”예요.

기본 타입(primitive) 8가지: 성격만 정확히 잡으면 됩니다

기본 타입은 값 자체를 다루고(객체가 아님), 성능/메모리 측면에서 유리합니다. 대신 null을 가질 수 없고, 컬렉션에는 직접 담을 수 없어(예: List<int> 불가) 필요하면 래퍼 타입(Integer)을 씁니다.

분류 타입 크기 핵심 용도 실무 포인트
정수 byte 1B 바이너리/IO 일반 비즈니스 로직엔 거의 안 씁니다
정수 short 2B 레거시/바이너리 사용 빈도 낮음
정수 int 4B 기본 정수 대부분의 카운트/인덱스는 int로 충분
정수 long 8B 큰 범위 정수 시간(ms), DB PK, 파일 크기 등
실수 float 4B 그래픽/과학 계산 정밀도 낮아 일반 금액/정산엔 비추
실수 double 8B 기본 실수 “근사값” 계산에 사용, 금액엔 주의
문자 char 2B UTF-16 code unit 문자열은 보통 String으로 처리
논리 boolean JVM 의존 true/false 조건 플래그

금액/정산 같은 “정확해야 하는 소수”는 double이 아니라 보통 BigDecimal을 선택합니다. double은 0.1 같은 값이 이진 부동소수로 정확히 표현되지 않아 누적 오차가 생길 수 있어요.

참조 타입(reference): 실무는 사실 여기서 대부분 끝납니다

실무에서는 기본 타입보다 참조 타입을 더 많이 다룹니다. 특히 아래는 거의 매일 씁니다.

  • String: 텍스트 데이터의 표준
  • BigDecimal: 금액/정밀한 소수 계산
  • 날짜/시간: Instant, LocalDate, LocalDateTime, ZonedDateTime (Java 8+ java.time 권장)
  • 컬렉션: List, Map, Set (구현체는 보통 ArrayList, HashMap, HashSet)
  • Optional: 반환값이 “없을 수도 있음”을 표현할 때(특히 조회 결과)

var 키워드와 타입 추론: “타입을 없애는 문법”이 아니라 “컴파일러가 결정”합니다

var는 Java 10+에서 도입된 지역 변수(local variable) 타입 추론입니다. 핵심은 한 가지예요.

  • var컴파일 타임에 타입이 결정됩니다. 동적 타입이 아닙니다.
  • 필드(멤버 변수), 메서드 파라미터, 반환 타입에는 var를 쓸 수 없습니다.
  • 초기화가 반드시 필요합니다. (var x; 불가)
  • null로는 추론할 수 없습니다. (var x = null; 불가)

var는 “타입이 명확한데 코드가 장황해지는 경우”에 특히 좋습니다. 예를 들어 제네릭이 길거나 스트림 파이프라인 중간 변수처럼 오른쪽이 타입을 충분히 말해줄 때요.

flowchart LR
A[초기화 식] --> B{컴파일러가 타입 계산}
B --> C[var 변수의 고정 타입 결정]
C --> D[이후에는 해당 타입으로만 사용 가능]

var는 런타임이 아니라 컴파일 시점에 타입이 고정된다는 흐름을 나타냅니다.

 

코드 예제: 기본 타입/참조 타입/var/BigDecimal/날짜까지 한 번에 실행

아래 코드는 Java 17에서 그대로 실행됩니다(단일 파일). “어떤 타입을 언제 쓰는지”를 감으로 잡기 좋게 구성했습니다.

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;

public class VariablesAndTypesDemo {
    public static void main(String[] args) {
        // 1) 기본 타입 8가지 중 실무에서 자주 만나는 것들
        int count = 3;
        long epochMillis = System.currentTimeMillis(); // 시간(ms)은 long이 안전합니다
        boolean active = true;
        double ratio = 0.1; // 근사값(부동소수). 금액에는 주의

        // 2) 참조 타입: String
        String name = "coffee";

        // 3) 금액: BigDecimal (double로 만들지 말고 문자열/정수 기반을 권장)
        BigDecimal price = new BigDecimal("19.99");
        BigDecimal quantity = BigDecimal.valueOf(count);
        BigDecimal total = price.multiply(quantity).setScale(2, RoundingMode.HALF_UP);

        // 4) 날짜/시간: java.time (레거시 Date/Calendar보다 권장)
        LocalDate today = LocalDate.now();
        Instant now = Instant.now();

        // 5) var: 지역 변수 타입 추론 (컴파일 타임에 타입이 고정됨)
        var items = new ArrayList<String>(); // var -> ArrayList<String>
        items.add(name);

        var stockByName = new HashMap<String, Integer>(); // var -> HashMap<String, Integer>
        stockByName.put(name, count);

        // 주의: var는 null로 추론 불가 (아래는 컴파일 에러)
        // var x = null;

        // 주의: var는 한 번 결정되면 타입이 바뀌지 않습니다 (아래는 컴파일 에러)
        // var n = 1;
        // n = "1";

        System.out.println("count(int) = " + count);
        System.out.println("epochMillis(long) = " + epochMillis);
        System.out.println("active(boolean) = " + active);
        System.out.println("ratio(double) = " + ratio);
        System.out.println("name(String) = " + name);
        System.out.println("total(BigDecimal) = " + total);
        System.out.println("today(LocalDate) = " + today);
        System.out.println("now(Instant) = " + now);
        System.out.println("items(var -> ArrayList<String>) = " + items);
        System.out.println("stockByName(var -> HashMap<String, Integer>) = " + stockByName);
    }
}

실무 팁

💡 실무에서는: int vs long 선택, “시간/ID”는 long을 기본으로 두세요

  • DB PK, 이벤트 ID, 타임스탬프(ms), 파일 크기처럼 커질 수 있는 값은 long이 안전합니다.
  • 반면 컬렉션 인덱스나 페이지 사이즈 같은 “명백히 작은 범위”는 int가 더 자연스럽고 API도 대부분 int를 받습니다.

💡 실무에서는: var는 “짧게”가 아니라 “명확하게” 쓰는 도구로 보세요

  • 오른쪽 초기화 식만 봐도 타입이 명확하면 var가 가독성을 올립니다(특히 제네릭).
  • 반대로 var data = get();처럼 반환 타입이 모호하면, 타입을 명시하는 편이 유지보수에 유리합니다.
  • 팀 컨벤션으로 “스트림 체인 중간/제네릭 긴 경우만 var 허용” 같은 규칙을 정해두면 리뷰 비용이 줄어듭니다.

핵심 요약: 기본 타입 8가지는 “정수/실수/논리” 용도를 정확히 구분하는 게 전부입니다.
핵심 요약: 금액은 double 대신 BigDecimal, 날짜는 java.time을 기본으로 잡아두세요.
핵심 요약: var는 동적 타입이 아니라 “컴파일 타임 타입 고정”이며, 명확할 때만 쓰는 게 좋습니다.

다음 글: #04 연산자와 제어문 핵심 정리