배열은 변수와 사용법이 비슷한데, 차이점이 있다면 다음과 같이 []
사이에 숫자 번호를 넣어주면 된다. 배열의 위치를 나타내는 숫자를 인덱스(index)라 한다.
// 변수 값 대입
students[0] = 90;
students[1] = 80;
// 변수 값 사용
System.out.println("학생1 점수 : " + students[0]);
System.out.println("학생2 점수 : " + students[1]);
new int[5]
와 같이 5개의 요소를 가지는 int
형 배열을 만들었다면 인덱스는 0, 1, 2, 3, 4
가 존재한다.
여기서 주의해야 할 점이 있는데 인덱스는 0부터 시작한다는 것이다. 배열의 요소를 5개로 생성했지만, 인덱스는 0부터 시작한다. 따라서 사용 가능한 인덱스의 범위는 0 ~ (n - 1)
이 된다. 그래서 students[4]
가 배열의 마지막 요소이다.
만약 students[5]
와 같이 접근 가능한 배열의 인덱스 범위를 넘어가면 다음과 같은 오류가 발생한다.
인덱스 허용 범위를 넘어설 때 발생하는 오류
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
at array.Array1Ref1.main(Array1Ref1.java:15)
배열에 값을 대입하든, 배열의 값을 사용하든 간에 일반적인 변수와 사용법은 같다. 추가로 []
를 통해 인덱스만 넣어주면 된다.
students[0] = 90; // 1. 배열에 값을 대입
x001[0] = 90; // 2. 변수에 있는 참조값을 통해 실제 배열에 접근. 인덱스를 사용해서 해당 위치의 요소에 접근, 값 대입
students[1] = 80; // 1. 배열에 값을 대입
x001[1] = 80; // 2. 변수에 있는 참조값을 통해 실제 배열에 접근. 인덱스를 사용해서 해당 위치의 요소에 접근, 값 대입
// 1. 변수 값 읽기
System.out.println("학생1 점수 : " + students[0]);
// 2. 변수에 있는 참조값을 통해 실제 배열에 접근. 인덱스를 사용해서 해당 위치의 요소에 접근
System.out.println("학생1 점수 : " + x001[0]);
// 3. 배열의 값을 읽어옴
System.out.println("학생1 점수 : " + 90);
배열을 사용하면 이렇게 참조값을 통해서 실제 배열에 접근하고 인덱스를 통해서 원하는 요소를 찾는다.
자바의 변수 데이터 타입을 가장 크게 보면 기본형과 참조형으로 분류할 수 있다. 사용하는 값을 직접 넣을 수 있는 기본형, 그리고 방금 본 배열 변수와 같이 메모리의 참조값을 넣을 수 있는 참조형으로 분류할 수 있다.
int
, long
, double
, boolean
처럼 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입을 기본형(Primitive Type)이라 한다.int[] students
와 같이 데이터에 접근하기 위한 참조(주소)를 저장하는 데이터 타입을 참조형(Reference Type)이라 한다. 객체나 클래스를 담을 수 있는 변수들도 모두 참조형이다.배열은 왜 이렇게 복잡하게 참조형을 사용할까? 지금까지 배운 변수처럼 단순히 그 안에 값을 넣고 사용하면 되는 것 아닐까?
기본형은 모두 사이즈가 명확하게 정해져있다.
int i; // 4byte
long l; // 8byte
double d; // 8byte
그런데 배열은 다음과 같이 동적으로 사이즈를 변경할 수 있다.
int size = 10000; // 사용자가 입력한 값을 넣었다고 가정해보자.
new int[size]; // 이 코드가 실행되는 시점에 배열의 크기가 정해진다.
Scanner
를 사용해서 사용자 입력에 따라 size
변수의 값이 변하고, 생성되는 배열의 크기도 달라질 수 있다. 이런 것을 동적 메모리 할당이라 한다. 기본형은 선언과 동시에 사이즈가 정적으로 정해지지만, 참조형을 사용하면 이처럼 동적으로 크기가 변해서 유연성을 제공할 수 있다.