본문 바로가기
JAVA/문법

자바 객체 배열 선언/구현하기 + 얕은복사, 깊은복사 방법

by 스코리아 2023. 8. 21.

안녕하세요. 스코리아입니다.

이전 시간에는 자바 1차원 배열을 선언하는 방법과 초기화하는 방법에 대해서 알아보았습니다.

[이전 내용] 1차원 배열 선언, 초기화 방법 : https://skorea6.tistory.com/14

 

오늘은 자바 객체 배열을 선언/구현해 보고, 얕은 복사와 깊은 복사 방법을 예제와 함께 알아보겠습니다.

 

 

객체 배열 특징

  • 기본 자료형 배열은 선언과 동시에 배열의 크기만큼의 메모리가 할당됩니다.
  • 하지만, 객체 배열의 경우에는 요소가 되는 객체의 주소가 들어갈 메모리(4byte, 8byte..)만 할당되고 각 요소 객체는 생성하여 저장해야 합니다.
  • 객체 배열을 만들고 나면, 모든 index의 값은 null로 초기화됩니다.

객체 배열 선언, 구현

 

객체 배열 선언, 구현하기

  • Book.java 파일을 만들어, Book class를 구현해 보겠습니다.
public class Book {
	private String title;
	private String author;
	
	public Book() {}
	
	public Book(String title, String author) {
		this.title = title;
		this.author = author;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}
	
	public void showBookInfo() {
		System.out.println(title + ", " +author);
	}
}
  1. Book 생성자 2개, 그리고 멤버변수인 title(제목), author(글쓴이)에 대한 getter, setter 메소드를 생성해 주었습니다.
  2. showBookInfo() 메소드를 통해 멤버변수인 title과 author를 출력 가능하게끔 하였습니다.

  • BookArrayTest.java 파일을 만들어, 메인함수를 정의하고 Book 객체를 배열로 선언한 뒤, 출력해 봅시다.
Book[] library = new Book[5];

for(Book b : library) {
    System.out.println(b);
}

객체 배열 선언후 출력

  1. Book 객체 배열에 아무 값도 입력하지 않았으므로, 기본값인 null로 모두 초기화됩니다.
  2. 그러므로, 배열의 값들이 모두 null로 출력됩니다.

  • 이번에는 Book 객체 배열에 값을 추가해 보겠습니다. new Book()을 이용하여 index별로 값을 추가하였습니다.
Book[] library = new Book[5];

library[0] = new Book("아몬드1", "조1");
library[1] = new Book("아몬드2", "조2");
library[2] = new Book("아몬드3", "조3");
library[3] = new Book("아몬드4", "조3");
library[4] = new Book("아몬드5", "조4");

for(Book b : library) {
    System.out.println(b);
    b.showBookInfo();
}

객체 배열 값 추가 후 출력

  1. new Book() 키워드를 사용하여 새로운 Book 인스턴스를 객체 배열에 저장하였기 때문에, 각각의 배열 값들은 모두 다른 메모리 주소를 갖게 됩니다.
  2. b.showBookInfo() 메소드 호출로, title과 author가 잘 나오는 것을 볼 수 있습니다.

 

 

객체 복사 - 얕은 복사

  • 객체 주소만 복사되어, 한쪽 배열의 요소를 수정하면 같이 수정됩니다.
  • 즉, 두 배열이 같은 객체(메모리주소)를 가리킵니다.
  • 자바에서 제공되는 배열 복사 메서드: System.arrayCopy(src, srcPos, dest, destPos, length)
Book[] library = new Book[5];
Book[] copyLibaray = new Book[5];

library[0] = new Book("아몬드1", "조1");
library[1] = new Book("아몬드2", "조2");
library[2] = new Book("아몬드3", "조3");
library[3] = new Book("아몬드4", "조3");
library[4] = new Book("아몬드5", "조4");

// 얕은 복사 진행
System.arraycopy(library, 0, copyLibaray, 0, 5);

System.out.println("========= copy library =========");
for(Book b : copyLibaray ) {
    b.showBookInfo();
}

// library 값을 변경
library[0].setTitle("리눅스마스터");
library[0].setAuthor("김민지");

System.out.println("========= library =========");
for(Book b : library) {
    b.showBookInfo();
}

// copyLibrary 쪽에서도 값이 변경됨
System.out.println("========= copy library =========");
for(Book b : copyLibaray) {
    b.showBookInfo();
}

얕은복사 예제 - 결과값

  1. Stream.arraycopy를 이용하여 library 객체 배열 0번째 index부터 마지막 index까지 copyLibrary 객체 배열에 얕은 복사를 진행하였습니다.
  2. copyLibrary 배열 출력 결과, library 배열과 동일하게 잘 복사됨을 알 수 있습니다.
  3. library의 0번째 index 값을 변경해 보았습니다.
  4. library 배열에서 '리눅스마스터' , '김민지'로 변경된 것이 잘 보입니다.
  5. copyLibrary 배열에서도 '리눅스마스터' , '김민지'로 변경되었습니다. 그 이유는 두 배열이 얕은 복사를 하였으므로, 두 배열이 같은 객체(메모리주소)를 가리키기 때문입니다.

 

객체 복사 - 깊은 복사

  • 각각의 객체를 생성하여 그 객체의 값을 복사하여 배열이 서로 다른 객체를 가리키도록 만드는 것입니다.
  • 즉, 두 배열이 서로 다른 객체(메모리주소)를 가리킵니다.
Book[] library = new Book[5];
Book[] copyLibaray = new Book[5];

library[0] = new Book("아몬드1", "조1");
library[1] = new Book("아몬드2", "조2");
library[2] = new Book("아몬드3", "조3");
library[3] = new Book("아몬드4", "조3");
library[4] = new Book("아몬드5", "조4");

// 깊은 복사 진행
for(int i=0; i<library.length; i++) {
    copyLibaray[i] = new Book(library[i].getTitle(), library[i].getAuthor());
}

// library 값을 변경
library[0].setTitle("리눅스마스터");
library[0].setAuthor("김민지");

System.out.println("========= library =========");
for(Book b : library) {
    b.showBookInfo();
}

// copy library 쪽에서는 값이 변경되지 않음!
System.out.println("========= copy library =========");
for(Book b : copyLibaray) {
    b.showBookInfo();
}

깊은복사 예제 - 결과값

  1. library가 new Book()을 이용하여 새로운 객체를 만들어 값을 넣는 것처럼, copyLibrary도 new Book()을 이용하여 index마다 새로운 객체를 만들어, 깊은 복사를 진행하였습니다.
  2. library의 0번째 index 값을 변경해 보았습니다.
  3. library 배열에서 '리눅스마스터' , '김민지'로 변경된 것이 잘 보입니다.
  4. copyLibrary 배열에서는 값이 변경되지 않았습니다. 기존 값인 '아몬드1' , '조1' 그대로 출력됩니다. 그 이유는 두 배열이 깊은 복사를 하였으므로, 두 배열이 다른 객체(메모리주소)를 가리키기 때문입니다.

 


지금까지 자바(Java) 객체 배열을 선언 및 구현해 보았고, 얕은 복사와 깊은 복사 사용방법에 대해서 알아보았습니다.

읽어주셔서, 감사합니다.