객체 배열은 참조 자료형으로 선언해 사용할 수 있습니다.
💻 Book 클래스
package array;
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);
}
}
💻 BookArray main 클래스
각 배열 요소에 인스턴스를 생성하는 코드
package array;
public class BookArray {
public static void main(String[] args) {
Book[] library = new Book[4];
library[0] = new Book("태백산맥", "조정래");
library[1] = new Book("무진기행", "김승옥");
library[2] = new Book("데미안", "헤르만 헤세");
library[3] = new Book("변신", "프란츠 카프카");
for(int i = 0; i<library.length; i++) {
library[i].showBookInfo();
}
}
}
배열을 복사하는 경우는 크게 두 가지로 나뉩니다
첫째, 기존 배열과 자료형 및 크기가 똑같은 배열을 새로 만들 때
둘째, 배열의 모든 요소에 자료가 꽉 차서 더 큰 배열을 만들어 기존 배열에 저장된 자료를 가져오려 할 때
System.arraycopy(src, srcPos, dest, destPos, length)
각 매개변수의 의미는 다음과 같다.
매개변수 | 의미 |
---|---|
src | 복사할 배열 이름 |
srcPos | 복사할 배열의 첫 번째 위치 |
dest | 복사해서 붙여 넣을 대상 배열 이름 |
destPos | 복사해서 대상 배열에 붙여 넣기를 시작할 첫 번째 위치 |
length | src에서 dest로 자료를 복사할 요소 개수 |
📂 예제코드
package array;
public class ArraCopy {
public static void main(String[] args) {
int[] array1 = {10,20,30,40,50};
int[] array2 = {1,2,3,4,5};
System.arraycopy(array1, 0, array2, 1, 4); //araycopy() 메서드
for(int i = 0; i<array2.length; i++) {
System.out.println(array2[i]);
}
}
}
array1 배열에서 array2 배열로 요소 값을 복사하는 코드입니다.
이때 복사할 대상 배열의 전체 길이가 복사할 요소 개수보다 작다면 오류가 나게 됩니다.
배열의 깊은 복사와 얕은 복사는 배열의 요소 값 변경시 영향을 미치게 됩니다.
복사된 배열이나 원본 배열이 변경될 때 두 배열의 값 모두 함께 변경된다. (변경 사항이 생겨도 항상 같은 값을 가지게 된다.)
📂 예제코드
package array;
public interface ArrayCopy2 {
public static void main(String[] args) {
...
bookArray1[0].setBookname("나목");
bookArray1[0].setAuthor("박완서");
System.out.println("===bookArray1===");
for(int i = 0; i<bookArray1.length; i++) {
bookArray1[i].showBookInfo();
}
System.out.println("===bookArray2===");
for(int i = 0; i<bookArray2.length; i++) {
bookArray2[i].showBookInfo();
}
}
}
bookArray1 배열의 0번째 요소를 변경했는데, bookArray2 배열까지 함께 변경됐다. 왜일까?
객체 배열 요소에 저장된 값은 인스턴스 자체가 아니고 인스턴스의 주소 값이기 때문이다. 결국 두 배열의 다른 요소가 같은 인스턴스를 가리키고 있기 때문에 복사되는 배열의 인스턴스 값이 변경되면 두 배열 모두 영향을 받는다.
이와 같은 복사를 주소 값만 복사한다고 해서 '얕은 복사'라고 한다.
🤩 그렇다면 두 배열의 각 요소가 서로 다른 인스턴스를 가리켜 하나의 배열이 변경돼도 서로에게 영향을 미치지 않게 하려면 어떻게 해야할까?
복사된 배열이나 원본 배열이 변경될 때 서로 간의 값은 바뀌지 않는다.
ㅋㅌ ㄴㄴ
📂 예제코드
package array;
public class ObjectCopy3 {
public static void main(String[] args) {
Book[] bookArray1 = new Book[3];
Book[] bookArray2 = new Book[3];
bookArray1[0] = new Book("태백산맥", "조정래");
bookArray1[1] = new Book("무진기행", "김승옥");
bookArray1[2] = new Book("데미안", "헤르만 헤세");
bookArray2[0] = new Book();
bookArray2[1] = new Book();
bookArray2[2] = new Book();
for(int i = 0; i<bookArray1.length; i++) {
bookArray2[i].setBookname(bookArray1[i].getBookname());
bookArray2[i].setAuthor(bookArray1[i].getAuthor());
}
for(int i = 0; i<bookArray2.length; i++) {
bookArray2[i].showBookInfo();
}
bookArray1[0].setBookname("나목");
bookArray1[0].setAuthor("박완서");
}
}
깊은 복사를 할 경우 bookArray1 배열의 값을 바꿔도 bookArray2 배열에 영향을 미치지 않는다는 사실을 알 수 있습니다.
📌 자바 5부터 제공되는 향상된 for문 (enhanced for loop)입니다.
for(변수:배열) {
반복 실행문;
}
배열의 처음에서 끝까지 모든 요소를 참조할 때 사용하면 편리한 반복문입니다.
향상된 for문은 배열 요소 값을 순서대로 하나씩 가져와서 변수에 대입합니다. 따로 초기화와 종료 조건이 없기 때문에 배열의 시작 요소부터 끝 요소까지 실행하게 됩니다!
📂 예제코드
package array;
public class EnhancedForLoop {
public static void main(String[] args) {
String[] strArray = {"Java", "C", "JavaScript", "Go", "Kotlin"};
for(String lang:strArray) {
System.out.println(lang);
}
}
}
String형으로 선언된 strArray 배열에 문자열 5개를 저장하고,
향상된 for문을 사용해 String형 lang 변수에 strArray 배열 요소의 값을 순서대로 가져와 대입해 출력한 코드입니다!