Ch5 - 배열 2
객체를 참조하는 배열
P.165
"참조타입(클래스, 인터페이스)" 배열은 각 항목에 객체의 번지를 가지고 있다. 대표적인 객체 배열 String[]배열은 각 항목에 문자열이 아닌 String 객체의 주소를 가지고 참조한다."
문자열을 참조하는 배열
객체를 참조하는 배열은 1차원 배열이더라도 내부 구조는 기본타입의 2차원 배열과 유사하다. 힙 영역안에 객체의 주소를 가진 배열과 각각의 객체들이 존재한다. (그림 참조)
//문자열을 참고하는 배열
String[] sA = new String[3]; //1차원 배열
sA[0] = "Java" //Java란 문자열이 힙 영역에 생기고 주소값이 0열에 들어감
sA[1] = "Java" //new생성자를 사용하지 않고 문자열이 같으므로 같은 객체를 공유, 0열의 주소를 카피해서 1열에 들어감
sA[2] = new String("Java") //새로운 Java 문자열이 생성되고, 그 주소값이 2열에 들어감
//객체의 번지 비교
System.out.println(sA[0] == strArray[1]); //true(같은 객체를 참조)
System.out.println(sA[0] == strArray[2]); //false(다른 객체를 참조)
//문자열 비교
System.out.println(sA[0].equals(strArray[2])); //true
객체 배열의 생성
new를 통해 객체배열의 변수를 선언할 경우 힙 메모리에 배열이 생성되는데, 이 때 각 배열의 항들은 또 다시 참조할 객체의 주소값을 가진다. sssA는 초기값을 주지 않은 String 배열이므로, 참조할 객체가 존재하지 않아 sssA[index]의 값도 null이다.
한편, pA 참조변수의 선언은 이미 Person이라는 클래스가 생성된 전제하에 가능하기 때문에, pA[index]의 값들은 참조할 각각의 Person 객체의 주소값을 가진다.
단, 엄밀히 말해 두 수행문은 완전히 같지 않은데, 그 이유는 Person[]pA = new Person[3];으로 변수를 선언한다면 pA[index]의 값들은 null을 가지기 때문이다. (메모리 구조 Check 필요)
// 객체 없는 문자열 배열
String[] sssA = new String[3]; //힙메모리에 배열 생성
System.out.println(sssA[0]); //null(참조하는 객체가 없음)
System.out.println(sssA[1]); //null(참조하는 객체가 없음)
//같은 구조의 초기값을 넣는 배열 만들기
Person[] pA = { new Person(), new Person(), new Person() };
Person[] pA = new Person[3];
객체 배열의 생성과 구조
sArr변수가 스택 메모리에 생성되고, 힙메모리에는 두개의 Student 객체와 연결된 배열 sArr이 생성된다. sArr[0]은 "홍길동", 10의 자료를 가진 객체의 주소값을 저장하고 있으며 sArr[1]은 "이순신", 12의 자료를 가진 객체의 주소값을 저장한다.
package p8; //객체배열의 구조
public class Array166Ex01 {
public static void main(String[] args) {
Student[] sArr = new Student[2];
sArr[0] = new Student();
sArr[1] = new Student();
sArr[0].name = "홍길동";
sArr[0].age = 10;
sArr[1].name = "이순신";
sArr[1].age = 12;
}
}
class Student{
String name;
int age;
}