- Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.
- Section 1. 자바의 핵심 - 객체지향 프로그래밍
- 18강 "객체 배열 사용하기"
- 객체 배열 만들기 > 배열 복사하기 > 객체 배열 복사하기 > 향상된 for문
예제는 Book 클래스를 생성하여 객체 배열을 만들어 보았다.
public class Book {
private String bookName;
private String author;
public Book() {}
public Book(String bookName, String author) {
this.bookName = bookName;
this.author = author;
}
public void showBookInfo() {
System.out.println(bookName + ", " + author);
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
main이 있는 BookArray 클래스에서 객체 배열을 생성한 후 출력하면 null로 초기화되어 있는 것을 확인할 수 있다.
public class BookArray {
public static void main(String[] args) {
Book[] library = new Book[5];
for(int i=0; i<library.length; i++) {
System.out.println(library[i]);
}
}
}
int, double과 같은 기본 자료형으로 배열을 생성하면 해당 자료형이 차지하는 크기(int면 4byte 등)와 배열의 개수만큼의 공간이 만들어진다.
하지만 객체 배열에서는 처음부터 객체가 만들어지는 것이 아니라 객체가 가리킬 주소의 자리가 만들어진다. 때문에 나중에 객체를 new 키워드를 통해 직접 생성해주어야 한다.
즉, 위 코드는 library 배열에 Book 객체가 5개 생성된 것이 아니라 주소의 자리가 5개 생성된 상태이다.
따라서 그림처럼 배열 안에 다시 객체를 넣어주어야 한다.
public class BookArray {
public static void main(String[] args) {
Book[] library = new Book[5];
library[0] = new Book("태백산맥", "조정래");
library[1] = new Book("데미안", "헤르만 헤세");
library[2] = new Book("어떻게 살 것인가", "유시민");
library[3] = new Book("토지", "박경리");
library[4] = new Book("어린 왕자", "생텍쥐페리");
for(int i=0; i<library.length; i++) {
System.out.println(library[i]);
}
for(int i=0; i<library.length; i++) {
library[i].showBookInfo();
}
}
}
배열의 각 자리에 Book 객체를 생성하였고, 객체 주소를 반환하는 것을 확인할 수 있다.
매개변수 | 설명 |
---|---|
src | 복사할 배열 이름 |
srcPos | 복사할 배열의 첫 번째 위치 |
dest | 복사해서 붙여 넣을 대상 배열 이름 |
destPos | 복사해서 대상 배열에 붙여 넣기를 시작할 첫 번째 위치 |
length | src에서 dest로 자료를 복사할 요소 개수 |
public class ArrayCopy {
public static void main(String[] args) {
int[] arr1 = {10, 20, 30, 40, 50};
int[] arr2 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
System.arraycopy(arr1, 0, arr2, 1, 4);
for(int i=0; i<arr2.length; i++) {
System.out.println(arr2[i]);
}
}
}
System.arraycopy(arr1, 0, arr2, 1, 4); 을 해석해보면
arr1의 0번째부터 복사할 것이고, arr2의 1번째부터 붙여넣을 것인데, 4개를 복사할 것이라는 의미이다.
arr2를 출력해보면 0번째 요소는 바뀌지 않고 1번째부터 4개는 변한 것을 확인할 수 있다.
붙여넣을 배열의 size가 복사할 size를 초과하면 에러가 발생한다.
public class ObjectCopy {
public static void main(String[] args) {
Book[] bookArr1 = new Book[5];
Book[] bookArr2 = new Book[5];
bookArr1[0] = new Book("태백산맥", "조정래");
bookArr1[1] = new Book("데미안", "헤르만 헤세");
bookArr1[2] = new Book("어떻게 살 것인가", "유시민");
bookArr1[3] = new Book("토지", "박경리");
bookArr1[4] = new Book("어린 왕자", "생텍쥐페리");
//bookArr1의 객체를 boorArr2에 복사
System.arraycopy(bookArr1, 0, bookArr2, 0, 5);
//bookArr1의 배열을 수정
bookArr1[0].setBookName("나목");
bookArr1[0].setAuthor("박완서");
//bookArr2 출력
for(int i=0; i<bookArr2.length; i++) {
bookArr2[i].showBookInfo();
}
}
}
bookArr2에는 bookArr1의 값이 복사된 것이 아니라 주소가 복사된 것이라 bookArr1의 요소를 수정하면 bookArr2의 요소도 함께 수정된다.
(정확히는 함께 수정되는 것이 아니라 동일한 인스턴스 주소를 가리키고 있으므로 인스턴스가 수정되면 동시에 바뀌는 것이다.)
public class ObjectCopy {
public static void main(String[] args) {
Book[] bookArr1 = new Book[5];
bookArr1[0] = new Book("태백산맥", "조정래");
bookArr1[1] = new Book("데미안", "헤르만 헤세");
bookArr1[2] = new Book("어떻게 살 것인가", "유시민");
bookArr1[3] = new Book("토지", "박경리");
bookArr1[4] = new Book("어린 왕자", "생텍쥐페리");
//bookArr2 배열에 Book 객체 생성 후 bookArr1의 인스턴스를 대입
Book[] bookArr2 = new Book[5];
for(int i=0; i<bookArr2.length; i++) {
bookArr2[i] = new Book();
bookArr2[i].setBookName(bookArr1[i].getBookName());
bookArr2[i].setAuthor(bookArr1[i].getAuthor());
}
//bookArr1의 배열을 수정
bookArr1[0].setBookName("나목");
bookArr1[0].setAuthor("박완서");
//bookArr2 출력
for(int i=0; i<bookArr2.length; i++) {
bookArr2[i].showBookInfo();
}
}
}
이렇게 하면 서로 다른 인스턴스의 메모리를 요소로 가지게 된다.
객체 배열을 복사할 때는 반드시 깊은 복사를 해야하는 것이 아니라, 복사한 배열이 수정될 일이 없다면 얕은 복사를, 수정될 일이 있다면 깊은 복사를 하면 되는 것이다.
// 기본 문법
for(자료형 변수 : 배열){
반복 실행문;
}
// 사용 예제
public class EnhancedForLoop {
public static void main(String[] args) {
String[] strArr = {"Java", "Android", "C", "JavaScript", "Python"};
for(String s : strArr) {
System.out.println(s);
}
}
}
변수에 배열의 0번째부터 마지막 요소까지 순차적으로 대입되며, 변수의 자료형은 배열의 자료형과 일치해야 한다.