본문 바로가기
Java/Java

this키워드(this.)와 this()메소드

by 박채니 2022. 3. 17.
SMALL

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


☞ this 키워드 (this.)

클래스의 외부에서 멤버(필드, 메소드, 이너클래스)를 호출 하기 위해선 반드시 객체를 생성한 후 호출해야 했습니다.

하지만, 같은 클래스 내에서는 객체 생성 없이 호출 할 수 있었습니다.

다만! 사용 가능한 멤버는 항상 객체 속에서만 존재합니다. 

 

그렇다면 어떻게 객체 생성 없이 사용할 수 있었을까요?

모든 메소드에는 자신이 포함된 클래스 객체를 가리키는 this라는 참조 변수가 있습니다. 

다만, this.을 생략하면 JVM이 자동으로 생성해주기 때문에 클래스 내부에서 필드와 메소드를 그대로 사용할 수 있었던 것이죠.

(단, 지역변수는 멤버가 아니므로 this이 안 붙음!)

 

class A {
	int m;
	int n;
	
	public void init(int a, int b) {
		int c;
		c = 3;
		this.m = a;	//this 생략 가능
		this.n = b;	//this 생략 가능
	}
	
	public void work() {
		this.init(2, 3);	//this 생략 가능
	}
}

public class thisStudy {
	public static void main(String[] args) {
		A a = new A();
		a.work();
		System.out.println(a.m);
		System.out.println(a.n);
	}
}

@콘솔출력값
2
3

이렇게 원래는 this.이 숨어져있던 것입니다.

 

this.을 명시적으로 붙여줘야 하는 상황을 알아보겠습니다.

class A {
	int m;
	int n;
	
	public void init(int m, int n) {
		m = m;
		n = n;
	}
	
	public void work() {
		init(2, 3);
	}
}

public class thisStudy {
	public static void main(String[] args) {
		A a = new A();
		a.work();
		System.out.println(a.m);
		System.out.println(a.n);
	}
}

@콘솔출력값
0
0

이렇게 필드와 지역변수(init의 매개변수)의 이름이 같은 경우에는 this.을 명시적으로 붙여줘야 합니다.

 

필드에 선언된 m, n은 전역변수로 클래스 전체에서 사용할 수 있고,

매개변수로 넘어온 m, n은 지역변수로 해당 메소드 안에서만 사용할 수 있습니다.

 

지역변수와 전역변수를 모두 사용할 수 있는 범위(init 메소드가 되겠죠)에서는 사용범위가 좁은 변수로 인식합니다.

즉 m = m, n = n과 같이 작성하면 둘 다 지역변수로 인식하여 this.이 자동으로 생성되지 않습니다.

따라서 지역변수 m, n에 지역변수 m, n의 값을 대입해주고 메소드가 끝나면 없어져 버리는 것이죠

 

그렇기 때문에 a.m, a.n을 출력하였을 때는 아무것도 대입 되지 않은 기본값 0이 출력 되는 것입니다.

 

이런 상황에서는 명시적으로 this.을 붙여줘야 합니다.

 

class A {
	int m;
	int n;
	
	public void init(int m, int n) {
		this.m = m;
		this.n = n;
	}
	
	public void work() {
		init(2, 3);
	}
}

public class thisStudy {
	public static void main(String[] args) {
		A a = new A();
		a.work();
		System.out.println(a.m);
		System.out.println(a.n);
	}
}

@콘솔출력값
2
3

이렇게 되면 넘어온 매개변수 m, n의 값을 this.m, this.n 필드의 m, n에 대입하게 되므로

a.m, a.n 을 출력하면 2, 3을 출력하게 됩니다.


☞ this() 메소드

this() 메소드는 자신이 속한 클래스 내부의 다른 생성자를 호출하는 명령입니다.

 

this() 메소드의 문법적 규칙

① 생성자의 내부에서만 사용할 수 있음

② 생성자의 첫 줄에 위치

 

class A {
	A() {
		System.out.println("첫 번째 생성자");
	}
	
	A(int a) {
		this();	//반드시 생성자 첫 줄에 위치!
		System.out.println("두 번째 생성자");
	}
}

public class thisStudy {
	public static void main(String[] args) {
		A a1 = new A();
		System.out.println();
		
		A a2 = new A(3);
	}
}

@콘솔출력값
첫 번째 생성자

첫 번째 생성자
두 번째 생성자

생성자가 2개 이므로 객체를 2개 생성하여 호출하였습니다.

A a1 = new A()에서 첫 번째 생성자가 실행이 되고,

A a2 = new A(3)에서는 두 번째 생성자가 실행되지만 내부에 this()를 포함하고 있으므로 자신의 또 다른 생성자인 A()를 호출하라는 것 입니다.

따라서 "첫 번째 생성자", "두 번째 생성자"가 출력 되는 것이죠.

 

this() 활용

class A {
	int m1, m2, m3, m4;
	
	A() {
		m1 = 1;
		m2 = 2;
		m3 = 3;
		m4 = 4;
	}
	
	A(int a) {
		this();
		m1 = a;
	}
	
	A(int a, int b) {
		this(a);
		m2 = b;
	}
	
	public void print() {
		System.out.print(m1 + " ");
		System.out.print(m2 + " ");
		System.out.print(m3 + " ");
		System.out.print(m4 + " ");
		System.out.println();
	}
}

public class thisStudy {
	public static void main(String[] args) {
		A a1 = new A();
		a1.print();
		
		A a2 = new A(10);
		a2.print();
		
		A a3 = new A(10, 20);
		a3.print();
	}
}

@콘솔출력값
1 2 3 4 
10 2 3 4 
10 20 3 4

A a2 = new A(10)를 하게 되면 A(int a) 생성자를 호출하게 됩니다.

A(int a) 생성자는 내부에서 this() 기본 생성자를 호출 하므로 A() 생성자를 호출 하게 됩니다.

A() 생성자에는 초기화된 필드들의 값들이 있으므로 그 값들을 가져온 후 m1의 값을 넘겨받은 10으로 변경하게 되므로 [10, 2, 3, 4] 를 호출 하게 되는 것이죠.

 

A a3 = new A(10, 20)를 하게 되면 A(int a, int b) 생성자를 호출하게 됩니다.

A(int a, int b) 생성자는 내부에서 this(a) 생성자를 호출하므로 A(int a) 생성자를 호출 하게 됩니다.

그렇다면 A(int a) 생성자 실행 → A(int a) 내부의 this()가 있으므로 A() 생성자 실행 → 초기화된 필드 값 불러옴 → 넘겨준 a의 값을 A(int a) 매개변수로 받아 m1에 대입 해줌 → 다시 A(int a, int b)로 돌아와서 m2에 매개변수 b를 대입해줌

이러한 과정을 통해 [10, 20, 3, 4]를 호출 하게 됩니다.

 

 

 

 

Do it! 자바 완전 정복을 참고하여 포스팅 하였습니다.

LIST