Java 17 기준으로 기본 타입 8가지와 참조 타입의 차이, var 타입 추론의 정확한 동작, 실무에서 자주 쓰는 타입 선택 기준을 한 번에 정리합니다.
코드를 읽다 보면 int는 익숙한데 long을 써야 하는지, double 대신 BigDecimal을 써야 하는지 헷갈릴 때가 많습니다. 또 Java 10+에서 var가 들어오면서 “그냥 다 var로 쓰면 되는 거 아닌가?” 같은 고민도 자주 생깁니다.
핵심 개념: Java 타입을 “정확히” 고르는 기준 (기본 타입 8가지 + 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 연산자와 제어문 핵심 정리
'JAVA' 카테고리의 다른 글
| Java 클래스와 객체 — 왜 나눠야 할까? (설계 기초부터 생성자·this·네이밍까지) (0) | 2026.02.14 |
|---|---|
| Java 연산자와 제어문 핵심 정리 — if/switch, 반복문, 비교 연산 실수 방지 (0) | 2026.02.13 |
| Java 개발 환경 한방에 세팅하기 (JDK + IntelliJ + Hello World) (0) | 2026.02.12 |
| Java는 왜 아직도 쓸까? — 생태계 현황과 JDK LTS 버전 선택 가이드 (0) | 2026.02.12 |
| 📦 Java Stream의 핵심, collect() 완전 정복 (0) | 2025.06.23 |