프로그램은 결국 값(데이터)을 다루는 일이에요. 그 값을 어디에 담고, 어떤 종류로 나눌지를 배우는 게 이번 장입니다. 상자에 이름표를 붙이는 이야기로 천천히 풀어볼게요.
변수(variable)는 값을 담아 두는 "상자"예요. 그리고 그 상자에는 나중에 다시 꺼내 쓰기 위해 이름(이름표)을 붙여요. 예를 들어 나이를 저장하고 싶다면, age라는 이름의 상자를 하나 만들고 그 안에 20이라는 값을 넣는 거죠.
그런데 자바는 상자를 만들 때 "이 상자에 어떤 종류의 값을 담을지"를 미리 정해야 해요. 이걸 자료형(type)이라고 해요. 정수를 담을 상자, 소수를 담을 상자, 글자를 담을 상자가 서로 다른 거죠. 이렇게 타입을 미리 정하는 언어를 정적 타입 언어라고 부르는데, 자바가 바로 그런 언어예요.
상자를 만드는 문장을 선언(declaration), 그 상자에 처음 값을 넣는 것을 초기화(initialization)라고 해요. 둘을 한 줄에 같이 쓸 수도 있어요.
int age; // 선언: "int(정수)를 담을 age 상자를 만든다"
age = 20; // 대입: age 상자에 20을 넣는다
int score = 100; // 선언 + 초기화를 한 줄에 (가장 흔한 형태)
int age; (아직 값은 없음)int age = 20;age = 30; (기존 20이 사라지고 30)
💡 =는 "같다"가 아니라 "오른쪽 값을 왼쪽 상자에 넣어라"라는 뜻이에요. 수학의 등호와 헷갈리지 마세요.
변수는 값을 바꿔 담을 수 있어요. 상자 안의 내용물을 새 값으로 갈아 끼우는 셈이죠. 그래서 이름이 "변(變)수" — 변하는 수예요.
int age = 20;
System.out.println(age); // 20
age = 21; // 상자 내용물을 21로 교체
System.out.println(age); // 21
name, _temp, $id2age ❌ (숫자는 두 번째 글자부터는 OK: age2 ✅)int, class, for 처럼 자바가 이미 쓰는 단어는 이름으로 못 씀age와 Age는 다른 변수예요userName, maxScore
규칙(1~4)은 어기면 에러가 나고, 관례(5)는 어겨도 돌아가지만 모두가 지키는 약속이라 꼭 따르는 게 좋아요.
int a = 20; 보다 int age = 20;이 훨씬 좋아요. 몇 달 뒤의 나(또는 동료)가 코드를 읽을 때 이름만 보고 뜻을 알 수 있으니까요.자바에는 미리 준비된 기본 자료형(primitive type)이 딱 8개 있어요. 값의 성격에 따라 정수 · 실수 · 문자 · 논리 네 그룹으로 나뉘어요. 각 타입은 담을 수 있는 크기(바이트)가 정해져 있어요. 상자가 클수록 더 큰 값을 담을 수 있지만 메모리도 더 써요.
int는 4바이트"라는 말은 그 상자가 차지하는 메모리 크기가 4바이트라는 뜻이에요. 숫자가 아무리 커도 상자 크기 안에서만 담을 수 있어요.| 그룹 | 타입 | 크기 | 대략적 표현 범위 · 값 | 용도 |
|---|---|---|---|---|
| 정수 | byte | 1바이트 | -128 ~ 127 | 아주 작은 정수, 바이트 데이터 |
short | 2바이트 | 약 -3.2만 ~ 3.2만 | 작은 정수 (잘 안 씀) | |
int ⭐ | 4바이트 | 약 -21억 ~ 21억 | 정수의 기본. 대부분 이걸 씀 | |
long | 8바이트 | 약 -922경 ~ 922경 (아주 큼) | int로 부족한 큰 정수(금액·시간) | |
| 실수 | float | 4바이트 | 소수 (정밀도 약 7자리) | 메모리 아낄 때의 소수 |
double ⭐ | 8바이트 | 소수 (정밀도 약 15자리) | 실수의 기본. 대부분 이걸 씀 | |
| 문자 | char | 2바이트 | 글자 한 개 ('가', 'A') | 단일 문자. 작은따옴표 ' ' |
| 논리 | boolean | 1바이트* | true / false | 참·거짓 (조건, 스위치) |
int, 실수는 double. 특별한 이유가 없으면 이 둘을 쓰면 돼요. byte·short·float은 "이런 게 있구나" 정도면 충분해요.float는 약 7자리, double는 약 15자리라, double이 더 촘촘하고 정확해요. 돈 계산처럼 정확함이 중요할 땐 double(또는 나중에 배울 별도 타입)을 쓰는 이유예요.그런데 큰 상자에 담을 값이라면 자바에게 그렇다고 알려줘야 해요. long에는 뒤에 L, float에는 뒤에 f를 붙여요. double은 기본이라 아무것도 안 붙여도 돼요.
long population = 8000000000L; // 80억 → int 범위를 넘어서 L 필수
float pi = 3.14f; // float에는 f (없으면 double로 취급돼 에러)
double rate = 3.14; // double은 기본, 접미사 불필요
char grade = 'A'; // 문자 한 개 → 작은따옴표
boolean isPassed = true; // 참 / 거짓
L·f를 붙여야 할까?
자바는 코드에 그냥 100이라고 쓰면 그걸 int로 봐요. 그래서 80억처럼 int(약 21억)를 넘는 숫자를 쓰면 "이건 int인데 너무 크다"며 에러가 나요. 그때 L을 붙여 "이건 long이야"라고 알려주는 거예요.3.14는 자바가 double로 봐요. 그래서 float 상자에 넣으려면 f를 붙여 "이건 float이야"라고 알려줘야 해요.
즉 접미사는 "이 값의 타입을 이걸로 봐 달라"는 표시예요. 다음 절에서 리터럴의 기본 타입을 더 자세히 봅니다.
boolean은 왜 크기가 애매할까?boolean은 true / false 딱 두 값만 있으니 이론적으로는 1비트면 충분해요. 그런데 컴퓨터가 데이터를 다루는 최소 단위가 보통 바이트(8비트)라, 실제로는 JVM 구현에 따라 처리돼요.
그래서 어떻게?
자바 명세는 boolean의 정확한 크기를 못 박지 않았어요. 그래서 시험에서 "boolean은 몇 바이트?"가 나오면 보통 1바이트로 답하지만, 진짜 핵심은 "true/false 두 값만 담는다"는 거예요. 크기보다 역할을 기억하세요.
리터럴(literal)은 코드에 직접 적어 넣은 고정된 값이에요. int age = 20;에서 20이 바로 리터럴이죠. 문자 'A', 참 true, 소수 3.14도 전부 리터럴이에요.
핵심은 이거예요. 자바는 리터럴마다 "기본 타입"을 미리 정해 두고 있어요.
100, -7)의 기본 타입은 int → 그래서 long이 필요하면 100L3.14, 0.5)의 기본 타입은 double → 그래서 float이 필요하면 3.14f
💡 정리: 정수는 int, 실수는 double이 기본이에요. 이걸 벗어나고 싶을 때만 L·f를 붙이면 돼요.
정수 리터럴은 10진수 말고 다른 진법으로도 쓸 수 있어요. 앞에 정해진 표시를 붙이면 돼요.
0b11010·0x1A·26은 모두 같은 수랍니다.| 진법 | 접두사 | 예시 | 10진수 값 |
|---|---|---|---|
| 10진수 (기본) | 없음 | 26 | 26 |
| 16진수 | 0x | 0x1A | 26 |
| 8진수 | 0 | 032 | 26 |
| 2진수 | 0b | 0b11010 | 26 |
또, 큰 숫자는 언더스코어( _ )로 자릿수를 끊어 읽기 좋게 쓸 수 있어요. 실행에는 아무 영향이 없고, 사람 눈에만 편해요.
int hex = 0x1A; // 16진수 → 26
int bin = 0b1101; // 2진수 → 13
int big = 1_000_000; // = 1000000 (언더스코어는 무시됨, 가독성용)
long salary = 50_000_000L; // 5천만 (long이라 L)
_1000(맨 앞), 1000_(맨 뒤), 1_.5(소수점 옆)처럼 쓰면 에러예요. "숫자와 숫자 사이 구분자"라고 기억하세요.자바의 자료형은 크게 두 갈래예요. 지금까지 본 8개는 전부 기본형(primitive)이고, 그 외 모든 것(String, 배열, 클래스로 만든 객체 등)은 참조형(reference)이에요.
String(문자열)이나 배열처럼, 기본형 8개를 뺀 나머지가 다 객체에 해당해요. 지금은 "기본형보다 크고 복잡한, 통째로 다루는 값" 정도로만 알아 두면 돼요. 객체를 직접 만들고 다루는 방법은 뒤의 클래스·객체 챕터에서 제대로 배워요.int x = 20; 이면 상자 안에 진짜 20이 들어 있어요. 이 값들은 스택(stack)이라는 빠른 메모리에 놓여요.가장 자주 만나는 참조형이 바로 String(문자열)이에요. 여러 글자를 담고, 큰따옴표 " "로 씁니다. String은 참조형이지만 워낙 많이 쓰여서 자바가 기본형처럼 편하게 쓸 수 있게 특별 대우해 줘요.
char initial = 'K'; // 문자 1개 → char, 작은따옴표
String name = "Kim"; // 여러 글자 → String, 큰따옴표
int n1 = 20; // 기본형: 상자에 값 20이 직접
String s1 = "hello"; // 참조형: 상자엔 주소, 실제 문자열은 힙에
char vs String
char = 글자 딱 한 개, 작은따옴표. 'A', '가', '7' ✅ / 'AB' ❌ (두 글자 불가)String = 글자 0개 이상 여러 개, 큰따옴표. "A", "Hello", "" ✅
💡 따옴표를 헷갈리면 바로 에러예요. "한 글자면 작은따옴표(char), 문장이면 큰따옴표(String)"로 외우세요. "A"와 'A'는 겉보기엔 비슷해도 타입이 완전히 달라요.
int, char, boolean…)은 대개 기본형, 대문자로 시작하는 타입(String, Scanner…)은 참조형(클래스)이에요. 완벽한 규칙은 아니지만 처음엔 아주 유용한 눈썰미예요.변수는 값을 바꿀 수 있는 상자였죠. 그런데 때로는 "한 번 정하면 절대 못 바꾸게" 잠그고 싶을 때가 있어요. 원주율 3.14, 최대 인원수처럼요. 그럴 때 final을 붙이면 상수(constant)가 돼요. 상수에 다시 값을 넣으려 하면 에러가 나요.
final int MAX_SIZE = 100; // 상수 선언 (더는 못 바꿈)
// MAX_SIZE = 200; // ❌ 에러! final은 재대입 불가
final double PI = 3.14159;
System.out.println(PI); // 3.14159 (읽기는 자유)
final 상수는 관례상 모두 대문자로, 단어 사이는 밑줄로 씁니다. 예: MAX_SIZE, PI, TAX_RATE. 이렇게 하면 코드에서 "아, 이건 바뀌지 않는 값이구나"가 한눈에 보여요.반대로, 타입을 일일이 쓰기 귀찮을 때도 있어요. 자바 10부터는 var를 쓰면 자바가 오른쪽 값을 보고 타입을 알아서 추론해 줘요. 이걸 타입 추론(type inference)이라고 해요.
var msg = "hi"; // 오른쪽이 문자열 → 자바가 String으로 추론
var count = 10; // 오른쪽이 정수 → int로 추론
var pi = 3.14; // 오른쪽이 실수 → double로 추론
// msg, count, pi 는 각각 String, int, double 로 확정돼요.
var 쓸 때 주의
1. 초기값이 꼭 있어야 해요 — var x; ❌ (값이 없으면 타입을 추론할 수 없음)var는 "타입을 안 쓴다"일 뿐, 타입은 여전히 고정돼요. var count = 10; 뒤에 count = "hi"; 는 ❌
입문 단계에서는 타입을 직접 쓰는 습관을 먼저 들이는 게 좋아요. var는 "이런 게 있다" 정도로만 알아두고, 나중에 코드가 길고 복잡해질 때 요긴하게 씁니다.
int는 0, double은 0.0, boolean은 false, 참조형(String 등)은 null. 이 "기본값" 개념은 뒤 챕터(클래스·객체)에서 다시 나오니 지금은 "지역 변수는 꼭 초기화해야 한다"만 챙기세요.
_·$로 시작, 숫자 시작·예약어 불가, 관례는 카멜케이스.byte(1)·short(2)·int(4)·long(8), 실수 float(4)·double(8), 문자 char(2), 논리 boolean. 기본은 int와 double.L, float은 f 접미사. 언더스코어(1_000)는 가독성용.String은 참조형이며 큰따옴표.'A'), String은 여러 글자·큰따옴표("A").MAX_SIZE), var는 지역 변수 타입 추론(Java 10+).