클라이언트/ 서버/ 엔지니어 " 게임 개발자"를 향한 매일의 공부일지

클래스와 객체 5 - 생성자 2 : this 레퍼런스 본문

프로그래밍 언어/자바

클래스와 객체 5 - 생성자 2 : this 레퍼런스

huenuri 2024. 8. 17. 12:03

이제 this에 대해서 학습해보려고 한다. 분량이 좀 많아서 this는 생성자에서 따로 떼어놓아 이곳에 기록하기로 했다. 사실 그동안 this는 정말 이해가 되지 않았고, 자바 수업을 들을 때도 무슨 말인지 잘 몰랐었다.

이번에 수업을 다시 들으며 확실히 이해할 수 있게 되어 정말 기쁘다.


 

 

 

 

1. this 레퍼런스

this는 자바의 중요한 키워드로서 단어 뜻 그대로 객체 자신을 가리키는 레퍼런스이다.

 

 

1) this의 기초 개념

this는 현재 실행되고 있는 메소드가 속한 객체에 대한 레퍼런스이다. this는 컴ㅊ파일러에 의해 자동 관리되므로 개발자는 this를 사용하기만 하면 된다. 

public class Circle {
	int radius;
    public Circle(int r) { this.radius = r; }
    public int getRadius() { return radius; }
}

 

this.radius는 현재 객체의 멤버 radius를 접근한다.


 

 

 

 

2) this의 필요성

Cicle 클래스에서 getRadius()는 this를 사용하지 않았다. 클래스 내에서 멤버 radius르 ㄹ접근할 때 굳이 this.radius로 할 필요가 없다.

return radius;		// return this.radius;와 동일

 

그렇다면 this는 언제 필요할까? 여기서 Circle(int r) 생성자의 매개변수를 r 대신 다음과 같이 radius로 벼경하는 것이 좋다.

public Circle(int radius) { radius = radius; }

 

이 코드에서 2개의 radius는 모두 Circle(int radius)의 개개변수 radius를 접근하기 때문에, 멤버 radius를 변경하지 못한다. 이럴 때 this를 이용하는 것이다.

또 메소드가 객체 자신의 레퍼런스를 니턴해야 하는 경우가 있는데 이럴 때 다음과 같이 this를 리턴하면 된다.

public Circle getMe() { return this; }		// getMe() 메소드는 객체 자신의 레퍼런스 리턴

 


 

 

 

 

3) this의 상세 설명

 

이 코드에서 main()은 3개의 Circle 객체를 생성한다. 객체가 있어야 this를 사용할 수 있다. ob1, ob2,ob3 객체에서 this는 각각 자기에 속한 객체에 대한 레퍼런스이다. ob1.set()이 실행될 때 this는 ob1 객체에 대한 레퍼런스이며, ob2.set()이 실행될 때 this는 ob2 객체에 대한 레퍼런스이다.


 

 

 

 

2. this()로 다른 생성자 호출

this()는 클래스 내에서 생성자가 다른 생성자를 호출할 때 사용하는 자바 코드이다. 

 

this()로 다른 생성자 호출

이전 예제에서 작성한 Book 클래스의 생성자를 this()를 이용하여 수정하라.

 

 

 

원래 예제에는 마지막 코드가 없었지만 노란줄이 떠서 이러한 코드를 추가해보았다. 생성된 객체를 사용하지 않아서 뜨는데 난 이런 경고 문구도 뜨는 게 무척 싫어서 이러한 부분도 모두 해결하는 편이다.


 

클래스 Book2의 구조

  • 필드 (Field)
    • String title: 책의 제목을 저장한다.
    • String author: 책의 저자를 저장한다.
  • 메서드 (Method)
    • void show(): 책의 제목과 저자를 출력하는 메서드이다.
    • Book2(): 기본 생성자이다. 제목과 저자를 빈 문자열로 초기화하고, "생성자 호출됨"이라는 메시지를 출력한다.
    • Book2(String title): 제목을 인자로 받아 저자를 "작자미상"으로 설정하는 생성자이다.
    • Book2(String title, String author): 제목과 저자를 인자로 받아 설정하는 생성자이다.

 

main 메서드의 실행 흐름

main 메서드에서 Book2 클래스의 객체(littlePrince, loveStory, emptyBook)를 생성하고, 이 객체의 정보를 출력한다.

  1. 객체 생성 및 생성자 호출
    • Book2 littlePrince = new Book2("어린왕자", "생텍쥐페리");
      • Book2 클래스의 두 번째 생성자 Book2(String title, String author)가 호출된다.
      • "어린왕자"와 "생텍쥐페리"를 인자로 받아, title과 author 필드를 초기화한다.
    • Book2 loveStory = new Book2("춘향전");
      • Book2 클래스의 세 번째 생성자 Book2(String title)가 호출된다.
      • "춘향전"을 인자로 받아, title 필드를 초기화하고 author 필드는 "작자미상"으로 설정한다.
    • Book2 emptyBook = new Book2();
      • Book2 클래스의 첫 번째 기본 생성자 Book2()가 호출된다.
      • title과 author 필드를 빈 문자열로 초기화하고, "생성자 호출됨"을 출력한다.
  2. show() 메서드 호출
    • littlePrince.show();
      • "어린왕자 생텍쥐페리"가 출력된다.
    • loveStory.show();
      • "춘향전 작자미상"이 출력된다.
    • emptyBook.show();
      • "" "" (빈 문자열)이 출력된다.

 

littlePrince와 loveStory 객체의 호출

  • littlePrince와 loveStory 객체는 main 메서드 내에서 생성되고, 생성자에 의해 초기화된다.
  • new Book2("어린왕자", "생텍쥐페리"); 이 부분이 객체를 생성하는 코드이며, 이 시점에서 Book2 클래스의 생성자가 호출된다.
  • 각각의 객체가 생성된 후, show() 메서드를 통해 각 객체의 title과 author 필드에 저장된 값을 출력한다.

이렇게 코드를 분석해보았다. 


 

 

3) this 사용시 주의할 점

  • this()는 반드시 생성자 코드에서만 호출할 수 있다
  • this()는 반드시 같은 클래스 내 다른 생성자를 호출할 때 사용한다
  • this()는 반드시 생성자의 첫 번째 문장이 되어야 한다.

this()의 호출은 생성자 코드의 첫 번째 문장이 되어야 하므로 Book 클래스의 다음 새성자에는 컴파일 오류가 발생한다.

public Book() {
	System.ou.printlin("생성자 호출됨");
    this("","");	// 컴파일 오류. this()는 생성자의 첫함 번째 문장이어야 함
}

 


 

 

 

 

 

3. 객체 치환 시 주의할 점

= 연산자로 객체를 치환하면 어떤 결과가 될까? 객체의 치환은 객체를 복사하는 것이 아니다. main() 메소드에서 다음과 같이 Circle 객체를 2개 생성하였다.

Circle3 ob1 = new Circle3(1);
Circle3 ob2 = new Circle3(2);

 

그리고 나서 다음 라인을 실행하면, ob2의 레퍼런스가 레퍼런스 x에 치환(대입)되어 s는 ob2가 가리키는 객체를 함께 가리키게 된다.

s = ob2;

 

 

다음 객체 치환 문장을 실행해보자. 역시 ob1의 레퍼런스가 ob2의 레퍼런스와 동일하게 되어 ob2의 객체를 함께 가리키게 된다. 그러고 나면 원래 ob1이 가리키던 객체는 아무도 가리키지 않게 되어 프로그램에서 접근할 수 없는 생태가 된다.

ob1 = ob2;

 

이 객체를 가비지(garbage)라고 부른다.

 

 

 

이렇게 ob1, ob2, s도 모두 ob2를 가리키게 되었다.

 

 


 

 

 

 

핵심 체크 문제 풀기

 

1. 다음 코드에서 잘못된 부분 수정하기

 

this(0)은 생성자의 제일 첫 문장이 되어야 한다.


 

 

 

 

 

2. 다음 코드의 오류 수정하기

 

n의 값이 할당한 후 사용하지 않아서 print 문을 넣어주었다. 그리고 오류가 뜬 이유는 기본 생성자가 없었기 때문이었다. ConstructorExample은 매개변수가 있는 생성자는 있지만 객체 생성 타입은 매개변수가 없는 타입이기에 기본 생성자를 만들어 주어야 한다.

 

 

이렇게 하면 매개변수가 있는 생성자가 있기에 객체 매개변수에 0을 넣어주자 오류가 발생하지 않는다. 기본 생성자가 없어도 말이다.

 

 

값은 int형이라면 어떤 숫자든지 상관 없었다.


 

 

 

3. this와 this()의 차이점

this는 현재 객체를 가리키는 참조이다. 인스턴스 변수와 지역 변수의 이름이 동일할 때 인스턴스 변수를 참조하기 위해 사용한다. 그리고 현재 객체의 다른 메서드를 호출할 때도 사용한다.

public class Example {
    int x;

    public void setX(int x) {
        this.x = x;  // 여기서 this.x는 인스턴스 변수, x는 메서드의 매개변수
    }
}

 

 

this() 키워드는 같은 클래스의 다른 생성자를 호출할 때 사용된다. 이 호출은 생성자 내부에서만 사용될 수 있으며 반드시 생성자의 첫번째 줄에 위치해야 한다. 생성자 오버로딩에서 코드 중복을 줄이고, 생성자 간 공통된 초기화 로직을 공유하기 위해 사용한다.

public class Example {
    int x;
    int y;

    // 기본 생성자
    public Example() {
        this(0, 0);  // 다른 생성자 호출
    }

    // 매개변수를 받는 생성자
    public Example(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

 


 

 

 

학습을 마치고

이렇게 해서 this 키워드를 사용한 학습과 문제까지 모두 풀어보았다. this와 this()에 대한 차이점도 알게 되었고 많은 것들을 배울 수 있었다. 이제 생성자에 대해서도 충분히 학습했으니 어제 풀어보려고 했던 수업 예제 나머지를 풀어보며 학습을 이어갈 것이다.