앞서 class에 대해(js-coding-study.tistory.com/12) 정리할때 나왔던 this에 대해 정리해보았다.
this는 instance method에만 존재하며 static method는 가지고 있지 않다.
instance method인지 아닌지 구분하는 법은 static이 달려있는지를 보면 되는데 달려있으면 static 아니면 instance다.
instance는 this를 가지고 있다고 했는데 그 this를 찾을수가 없다.
그 이유는 java자체에서 자동으로 제공을 해줘 코드상에서는 생략되기 때문인데
this는 instance method의 첫 번째 매개변수로 존재하지만 생략되어 보이지 않는다.
이 this의 용도는 객체를 호출 할 때 호출 한 객체가 무엇인지 구분하기 위해 그 객체를 담아 보내기 위해 사용된다.
왜 담아서 보내지? 라는 의문이 생길 수 있는데 그 이유는 같은 객체를 여러 이름으로 생성하게 되면 어느 객체가 어느 값이랑 연결되있는지를 구분하기 위해라고 답을 할 수 있다.
this를 instance method에 매개변수로 직접 선언해서 사용하게 되면 에러가 나는데 이는 안보이지만 이미 생성되있는 매개변수가 있어 중복을 방지하기 위해 에러가 나게된다.
직접 만들어 사용하는것은 불가능하고 사용하는 것만이 가능한데 그 사용법에는 어느 방법이 있는지도 알아보자.
class ThisExam {
private int a, b;
ThisExam(int a, int b) {
this.a = a;
this.b = b;
}
public static void disp(){
System.out.println("a = " + a + " b = " + b);
}
public static void main(String args[]){
ThisExam te = new ThisExam(10,20);
disp();
}
}
위와 같이 코드를 짰다고 가정을 하면
ThisExam te = new ThisExam(10,20); 이 부분에서 class 객체를 생성하고 10과 20을 매개변수로 보내 초기화도 해줬다,
객체가 생성되었으니 생성자가 실행되는데 생성자를 보면 매개변수로 a와 b를 받았다.
field에 선언된 변수들을 초기화 하려면 보통 a = a, b = b 이렇게 쓰는게 맞지만 앞에 있는 a가 어디에 있는 a인지를 구분하지 못하게된다.
그대로 disp함수를 호출하여 출력을 해보면 둘 다 0으로 나오게 되는데 그 이유는 함수내에서는 똑같은 이름의 field 변수와 매개변수로 받아온 변수가 있으면 매개변수로 받아온 변수가 지역변수기 때문에 그걸 사용해서 field값은 초기화가 되지 않아 0으로 나오게 된다.
이런 상황이 나오게 하지 않기 위해서는 초기화를 할 대상이 어디에 있는 변수인지를 구분해줘야 하는데 그때 사용하는 것이 바로 this이다.
위의 생성자를 보면 this.a = a; this.b = b;라 작성되어있는데 이렇게 변수명앞에 this.를 붙여 사용하게 되면 클래스 내부 field에 선언되어있는 변수로 인식하여 초기화가 정상적으로 진행된다.
그럼 변수명을 다르게 하면 되지 않냐 라는 생각이 들 수 있는데 틀린 생각은 아니다.
매개변수를 a, b가 아닌 _a, _b로 받게되면 this를 붙이지 않아도 되는데 붙여서 쓰는 이유는 지금이야 짜는 코드의 양이 적어 에러가 난곳을 찾기 쉽지만 코드가 길어지고 파일 또한 많아지게 되면 에러가 나는 곳을 찾기 힘들기에 변수 이름을 똑같이 하여 구분을 쉽게 하기 위해 매개변수를 field와 똑같이 이름을 붙여 this를 사용한다.
생성자에서 뿐만 아니라 setter/getter 에서 초기화를 할 경우에도 사용할 수 있다.
this라는 키워드 말고도 this();라는 키워드도 종종 볼 수 있는데
this()는 생긴대로 함수이다.
this()는 다른 생성자를 호출하는 함수인데 오직 생성자에서만 사용이 가능하다.
public class ThisCall {
int a, b;
public ThisCall(){
this(0,0);
// a = 0;
// b = 0;
}
public ThisCall(int a) {
this(a,0);
// ------------
// this.a = a;
// b = 0;
}
public ThisCall(int a, int b) {
this.a = a;
this.b = b;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
public static void main(String[] args) {
ThisCall tc1 = new ThisCall();
ThisCall tc2 = new ThisCall(1);
ThisCall tc3 = new ThisCall(2, 5);
System.out.println(tc1.getA() + "\t" + tc1.getB());
System.out.println(tc2.getA() + "\t" + tc2.getB());
System.out.println(tc3.getA() + "\t" + tc3.getB());
}
}
위 코드를 예시로 들어 보면
매개변수가 없는 생성자에서는 보통 주석처리한 부분처럼 초기화를 하게 되는데 위 코드는 this(0,0)으로 다른 생성자를 호출하여 사용하였다.
그 이유는 오버로딩된 함수들의 하는 일자체가 똑같아서 추후 유지보수를 위해 이런 방식으로 사용된다.
이 방식이 어떤 면에서 유지보수에 좋은가에 대해 생각해보면 만약 변수를 초기화하는 과정에서 에러가 발생했을 때
기존 방식으로 하면 어느 생성자에서 에러가 발생했는지를 하나하나 찾아가며 고쳐야하지만 위와 같은 방식으로 작성하게 되면 맨 마지막에 있는 매개변수가 2개인 생성자만 찾아가 수정하면 끝나기 때문에 이러한 방식을 사용한다.
이상으로 this가 무엇인지, 또 어디서 쓰이는지에 대해 정리가 끝이 났다.
(부족한 점이나 틀린점이 있다면 댓글로 부탁드립니다. 다른 글과 마찬가지로 정답이 아닌 주관적인 정리입니다.)
'Language > Java' 카테고리의 다른 글
[JAVA]급여관리 프로그램 (0) | 2021.02.12 |
---|---|
[JAVA] Class에 대해 (0) | 2021.02.03 |
[JAVA] Method호출 방식(Call by Reference, Name, Value) (0) | 2021.02.02 |
[JAVA]반, 학생 수 를 입력받는 성적 프로그램 (0) | 2021.02.01 |
[JAVA] 별찍기 (0) | 2021.01.30 |