변수 하나에 값 하나. 그런데 점수 30개, 이름 100개를 다뤄야 한다면? 변수 100개를 만들 순 없어요. 배열(array)은 같은 타입의 값 여러 개를 한 이름으로 묶어 관리하는 방법이에요. 인덱스만 익히면 절반은 끝납니다.
arr.length로 길이를 얻고, for·향상된 for로 순회할 수 있어요.m[i][j] 접근을 다룰 수 있어요.지금까지는 값 하나에 변수 하나였어요. 학생 3명 점수라면 score1, score2, score3처럼요. 그런데 학생이 30명, 100명이라면? 변수 100개를 손으로 만드는 건 현실적이지 않죠.
score1, score2…). 개수가 늘면 반복 처리도 어려워요.scores)에 값 여러 개를 담고, 번호(인덱스)로 골라 써요. 반복문과 찰떡궁합이에요.
💡 한 줄 정의: 배열은 "같은 타입의 값 여러 개를 한 이름으로 묶은, 크기가 고정된 상자들의 줄"이에요.
아래 그림처럼 배열은 칸(요소)이 나란히 줄지어 있고, 각 칸에는 0부터 시작하는 번호(인덱스)가 붙어 있어요. 이 번호로 원하는 칸을 콕 집어 읽고 씁니다.
int[] scores = {90, 85, 100, 70, 60};arr[0]이에요.new int[5]배열은 두 가지가 필요해요 — 선언(어떤 타입의 배열인지 이름 붙이기)과 생성(실제로 칸을 몇 개 만들지 정하기). 보통 한 줄에 같이 씁니다.
int[] arr = new int[5]; // int를 담는 5칸짜리 배열 생성
// 인덱스는 0부터 4까지: arr[0], arr[1], arr[2], arr[3], arr[4]
arr[0] = 10; // 첫 번째 칸에 10 저장
arr[4] = 50; // 마지막(다섯 번째) 칸에 50 저장
System.out.println(arr[0]); // 10
System.out.println(arr[4]); // 50
int[] arr = new int[5]; 한 조각씩
int[] — "int들을 담는 배열" 타입. 대괄호가 배열임을 뜻해요. (int arr[]처럼 뒤에 붙여도 되지만, int[] arr를 권장해요.)new int[5] — 실제로 5칸을 메모리에 만들어요. 이 5가 배열의 크기(length)예요.arr — 만든 배열을 가리키는 이름(변수).
⚠️ 크기는 생성할 때 정해지고, 그 뒤로 바꿀 수 없어요. 5칸으로 만들면 영원히 5칸이에요. (더 필요하면 CH에서 배울 컬렉션을 씁니다.)
0,1,2,3,4예요. 마지막 인덱스는 4지 5가 아니에요. arr[5]는 존재하지 않아 오류가 나요(뒤에서 설명).배열에 값을 넣는 방법은 크게 세 가지예요. 상황에 맞게 골라 쓰면 됩니다.
// ① 중괄호로 한 번에 채우기 (가장 간단, 선언과 동시에만 가능)
int[] a = {10, 20, 30}; // 3칸짜리, 값 10·20·30
// ② new int[]{ ... } — ①과 같지만, 나중에 대입할 때도 쓸 수 있음
int[] b;
b = new int[]{1, 2, 3, 4}; // ①의 { } 만 쓰면 이 자리에선 오류!
// ③ 빈 배열을 만든 뒤, 인덱스로 하나씩 대입
int[] c = new int[3]; // {0, 0, 0} 상태 (기본값)
c[0] = 100;
c[1] = 200;
c[2] = 300; // 이제 {100, 200, 300}
{ } 초기화의 함정
int[] a = {10, 20, 30}; 처럼 선언과 동시일 때만 중괄호만으로 됩니다.new int[]{ }를 써야 해요.
🚫 int[] a; a = {10, 20, 30}; → 컴파일 오류. ✅ a = new int[]{10, 20, 30};
arr[인덱스] = 값; 형태예요. 등호(=) 왼쪽에 칸을 두면 쓰기, 오른쪽에 두면 읽기예요. arr[0] = arr[1];은 "1번 칸 값을 읽어 0번 칸에 쓴다"는 뜻이죠.arr.length 와 배열 훑기배열의 칸 개수(크기)는 arr.length로 알 수 있어요. 아주 자주 헷갈리는 포인트 — 괄호가 없습니다. 메서드가 아니라 필드(속성)라서 arr.length()가 아니라 arr.length예요. (참고: 문자열 String은 반대로 str.length()로 괄호가 있어요.)
int[] arr = {10, 20, 30, 40, 50};
System.out.println(arr.length); // 5 ← 괄호 없음!
// ① 일반 for — 인덱스가 필요할 때 (0부터 length-1까지)
for (int i = 0; i < arr.length; i++) {
System.out.println(i + "번째: " + arr[i]);
}
// ② 향상된 for (for-each) — 값만 순서대로 필요할 때 더 간결
for (int v : arr) {
System.out.println(v); // 10, 20, 30, 40, 50
}
i < arr.length로 도는 표준형. 인덱스 i를 쓸 수 있어 "몇 번째"를 알거나 값을 수정할 때 좋아요.for (int v : arr). 인덱스 없이 값만 처음부터 끝까지 훑어요. 짧고 실수(범위 초과)가 없어요.
👉 값을 읽기만 하면 향상된 for가 편하고, 인덱스가 필요하거나 값을 바꿔야 하면 일반 for를 씁니다.
i < arr.length여야 해요. 실수로 i <= arr.length로 쓰면 마지막에 arr[length]를 건드려 범위 초과 오류가 납니다.new로 만든 배열은 저절로 "기본값"으로 초기화돼요.new int[5]처럼 값을 안 넣고 만들어도, 각 칸은 쓰레기값이 아니라 타입별 기본값으로 자동 초기화돼요. 그래서 int 배열은 만들자마자 전부 0이에요.
| 타입 분류 | 예시 | 배열 생성 시 기본값 |
|---|---|---|
| 정수형 | int, long, short, byte | 0 (long은 0L) |
| 실수형 | double, float | 0.0 |
| 문자형 | char | '\u0000' (코드값 0, 널 문자) |
| 논리형 | boolean | false |
| 참조형 | String, 객체 배열 | null |
int·double처럼 값을 직접 담는 기본형과 달리, String이나 배열·객체는 값 자체가 아니라 "그 값이 어디에 있는지(위치)"를 담는 타입이에요. 그래서 배열도 참조형이고, 아직 위치를 정하지 않은 칸의 기본값은 null(가리키는 곳 없음)이 돼요. 참고로 arr2 = arr1;처럼 배열을 통째로 대입하면 값이 복제되는 게 아니라 둘이 같은 배열 하나를 가리키게 돼요(이걸 얕은 복사라고 해요). 값까지 따로 복사하려면 요소를 하나씩 옮겨 담아야 합니다.int[] nums = new int[3]; // {0, 0, 0}
double[] rate = new double[2]; // {0.0, 0.0}
boolean[] on = new boolean[2]; // {false, false}
String[] names = new String[2]; // {null, null}
System.out.println(nums[0]); // 0
System.out.println(on[0]); // false
System.out.println(names[0]); // null
String[] names = new String[2];는 칸이 전부 null이에요. 값을 넣기 전에 names[0].length()처럼 쓰면 NullPointerException이 나요. 먼저 names[0] = "홍길동";으로 채운 뒤 써야 해요.① 범위를 벗어난 인덱스 — ArrayIndexOutOfBoundsException
크기 5짜리 배열의 유효 인덱스는 0~4예요. arr[5]나 arr[-1]처럼 범위 밖을 건드리면 실행 중에 이 예외가 터져요. (컴파일은 통과, 실행 때 발생!)
null인 값을 건드릴 때 자바가 예외를 던져(throw) 프로그램을 중단시켜요. 이름이 길고 무섭게 생겼지만, 사실은 "여기서 뭐가 잘못됐다"고 알려주는 신호랍니다.int[] arr = new int[5]; // 인덱스 0,1,2,3,4 만 유효
System.out.println(arr[5]); // 💥 ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
② 크기가 고정 — 칸을 더 추가할 수 없음
배열은 만들 때 정한 크기에서 늘리거나 줄일 수 없어요. 3칸 배열에 4번째 값을 "추가"하는 문법은 없습니다. 개수가 자주 바뀌는 데이터라면, 뒤 챕터에서 배울 컬렉션(예: ArrayList)이 더 알맞아요.
ArrayList로, .add()로 값을 계속 추가하고 .remove()로 뺄 수 있어요. "개수가 정해져 있으면 배열, 자주 바뀌면 컬렉션"이라고 기억하면 편해요. (자세한 건 뒤 챕터에서 다뤄요.)i < arr.length 조건으로 돌기 (<= 금지).0 <= idx && idx < arr.length인지 확인.arr[arr.length - 1]로 접근 (숫자를 손으로 쓰지 말기).
이 셋만 지켜도 ArrayIndexOutOfBoundsException은 거의 안 만나요.
지금까지는 한 줄로 늘어선 1차원 배열이었어요. 2차원 배열은 행(row)과 열(column)이 있는 표라고 생각하면 됩니다. 좌석표, 지도, 시간표 같은 걸 담기 좋아요.
int[][] m = new int[2][3]; // 2행 3열 (총 6칸), 전부 0으로 초기화
m[0][0] = 1; m[0][1] = 2; m[0][2] = 3; // 0번 행
m[1][0] = 4; m[1][1] = 5; m[1][2] = 6; // 1번 행
System.out.println(m[1][2]); // 6 ← 1번 행, 2번 열
System.out.println(m.length); // 2 ← 행의 개수
System.out.println(m[0].length); // 3 ← 0번 행의 열 개수
int[][] m = { {1,2,3}, {4,5,6} }; — m[행][열]2차원 배열을 전부 훑을 땐 for를 두 번 겹쳐(이중 for) 써요. 바깥 for는 행, 안쪽 for는 열을 돌아요.
int[][] m = { {1, 2, 3}, {4, 5, 6} };
for (int i = 0; i < m.length; i++) { // 행: 0, 1
for (int j = 0; j < m[i].length; j++) { // 열: 0, 1, 2
System.out.print(m[i][j] + " ");
}
System.out.println(); // 한 행 끝나면 줄바꿈
}
// 출력:
// 1 2 3
// 4 5 6
m.length는 행 개수, m[i].length는 그 행의 열 개수예요. 이중 for에서 안쪽 조건을 m[i].length로 쓰면, 행마다 열 개수가 달라도(가변 배열) 안전하게 돌 수 있어요.n 배열의 인덱스는 0 ~ n-1, 마지막은 arr[n-1].int[] arr = new int[5]; / 초기화 { } · new int[]{ } · arr[i]=값.arr.length(괄호 없음, 필드). 순회는 일반 for·향상된 for.int→0, double→0.0, boolean→false, 참조형→null.ArrayIndexOutOfBoundsException. 크기는 고정(추가 불가 → 컬렉션).int[][] m = new int[2][3];, m[i][j], 이중 for로 순회.