본문 바로가기

LECTURE/# java basic

[초급 JAVA]자바 this,static,final 지정예약어 - this & this()

반응형

this,static,final 지정예약어 - this & this()

By Commin November 29, 2016



 
ReservedWord_this.class

package reserved_word;
public class ReservedWord_this {
//this 는 '자기자신의 객체를 참조하는 예약어' 입니다.
//즉 , 클래스 내부에서 자신의 클래스를 지칭하는 객체라는 뜻입니다.
String name="commin's blog";
String address="Seoul";
ReservedWord_this(String name){
System.out.println(name);//결과: commin
//ReservedWord_this 의 생성자의 파라미터도 String의 name이라는 변수이고
//전영변수로 선언된 name도 같은 이름의 변수입니다.
//같은 클래스 안에서 전역변수는 클래스 전체에 영향을 미칩니다.
System.out.println(address);//결과값 : Seoul
//그러나 메서드안에서 같은 이름의 변수가 생성될 수 있는데요.
//이때 자바는 메서드안에 변수 즉, 지역변수로 선언된 변수를 사용하게됩니다.
//address 라는 변수는 현재 메서드 내부에서 같은 이름으로 선언된 변수가없으므로 지역변수를 가져다 쓴것이 보이시죠?
//그러면 같은이름으로 선언되었지만, 지역변수를 써야 할 때 어떻게할까요?
//그럴때 바로 this 를 씁니다.
System.out.println(this.name);//결과:commin's blog
//this 는 자기자신을 지칭하는 객체이므로 현재 클래스에 접근하여 멤버필드에 있는 name을 가져오는거죠.
//전에 말했듯이 메서드안에서 선언된 변수는 메서드가 끝나는 시점에 같이 없어지지만,
//지역변수로 선언된 변수는 클래스가 끝나지 않는 이상 계속해서 존재하게됩니다.
//그러니 객체로 접근한 클래스에서는 메서드안에 변수를 사용 할 수 없죠. 그래서 지역변수로 선언된 변수만을
//가져옵니다.
this.name=name;
//이런식으로 생성자에서 받은 데이터를 클래스의 지역변수로 옮겨닮는 코딩을 많이 하게됩니다.
System.out.println(this.name);//결과:commin;
}
public static void main(String [] ar){
new ReservedWord_this("commin");
}
}


this 란 ?

this란 예제 소스 주석에서도 언급했듯이 자기자신의 객체를 지칭하는 자바 예약어입니다. 주석에 설명을 많이 써놨으니 참고하셔서 보시면 되겠습니다.
이해를 돕기위하여 한가지 예를 들자면, A.class가 있다고 가정합시다. 코딩을 하다보면, A클래스내부에서 A클래스를 호출 해야 할 때가 있습니다. 그럴때 우리가 알고있는 객체를 생성해서 접근하면 어떻게 될까요?
예 열심히 데이터를 축적하고 조합되고있는 현재의 A 클래스가아닌, 초기상태의 A클래스가 다시 다른 공간에 생기게되는 현상이 발생합니다. 그럴때 this를 사용하면 자기자신 클래스를 가져오게되고 우리는 그걸이용하여 멤버필드를 호출하거나 값을 변경 할 수 있게되는겁니다.

직접 예제소스를 작성해보고 this를 붙였다가 지웠다가를 반복하여 실행해보세요. 그러면 이해 할 수 있을겁니다^^

this는 객체를 가져오지만 객체안에 생성자를 호출 하고싶을때는 어떻게 할까요? 그럴 때 사용하는것이 this() 예약어입니다.

 
ReservedWord_this2.class
package reserved_word;
public class ReservedWord_this2 {
//그러면 this()는 무엇일까요?
//쉽게생각해서 자기자신의 생성자를 호출하는 녀석입니다.
//this()를 호출하면 생성자가 호출되는데요. 메서드가 호출되는 순서도 같이 한번 보겠습니다.
//이해가 잘안되면 오류에 빠지기 쉬운 부분이기때문에 주의깊게 봐주세요.
String name;
String address;
int age;
public static void main(String [] ar){
new ReservedWord_this2();//첫번째로 인스턴스만 생성하여 ResevedWord_this2의 생성자를 호출해보겠습니다.
System.out.println("-------------------fin-------------------------");
/*마지막으로 콘솔창에 찍히며 프로그램이 끝납니다.*/
}
ReservedWord_this2(){//main 메서드에서 호출되어 처음으로 실행되는 생성자입니다.
this("commin");//this()를 이용하여 String 하나를 매개변수로 가지는 생성자를 호출합니다.
System.out.println("name : "+this.name+"\n"
+"address:"+this.address+"\n"
+"age:"+this.age);
System.out.println("-------------------1-------------------------");//생성자를 호출했으니, 다음 프로그래밍 순서는
//print()여서 -----1---- 이 콘솔창에 찍힐까요? 아닙니다. 메서드가 호출되면 호출된메서드가 끝나기전까진 돌아오지않습니다.
/*네번째로 콘솔창에 찍힙니다.
* 전역변수 3개 모두 데이터가 있죠. */
}
ReservedWord_this2(String name){//다음으로 호출된 녀석입니다. commin이라는 String 데이터를 가지고 왔죠.
this(name,"Seoul");//곧바로 this()를 이용해 다음 생성자를 호출합니다. 매개변수로받은 name을 바로 인자로 넣고. address를 추가하였습니다.
this.name=name;/*인자 두개의 생성자의 내용이 끝나면 이쪽으로 다시 돌아오겠죠?*/
System.out.println("name : "+this.name+"\n"
+"address:"+this.address+"\n"
+"age:"+this.age);
System.out.println("-------------------2-------------------------");/*세번째로 콘솔창에 찍힙니다.
전역변수에 age와 address, name까지 모두 데이터가 있습니다.*/
}
ReservedWord_this2(String name,String address){//3번째로 호출된 생성자입니다.
this(name,address,18);//곧바로 마지막 생성자를 호출합니다. 이번엔 age 를 추가하여 호출하였습니다.
this.address=address;/*마지막으로 호출된 생성자가 끝나면 다시 이쪽으로 돌아와서 소스를 읽습니다.*/
System.out.println("name : "+this.name+"\n"
+"address:"+this.address+"\n"
+"age:"+this.age);
System.out.println("--------------------3------------------------");/*두번째로 콘솔창에 찍힙니다.
전역변수에 age와 address는 데이터가있죠.*/
}
ReservedWord_this2(String name,String address,int age){//마지막으로 호출된 생성자입니다.
this.age=age;//이생성자에선 더이상 생성자를 호출하지않으므로 정상적인 순서로 프로그램이 실행됩니다.
System.out.println("name : "+this.name+"\n"
+"address:"+this.address+"\n"
+"age:"+this.age);
System.out.println("--------------------4------------------------");/*첫번째로 콘솔창에 찍힙니다.
전역변수 3개중 현재는 방금 데이터를 넣은
age만 데이터가 존재합니다.*/
}
//this 와 헷깔리는 예약어로는 super가있는데 이건 상속 파트에서 다룰겁니다.
//하지만 무서워할것없습니다. this가 자기자신을 지칭하는 객체라고만 확실히 이해하면됩니다 ^^.
}

this() 란?

this()를 사용하게되면, 자기자신의 생성자를 호출하게됩니다. 코딩을하다가 생성자를 이용하여 초기화를 다시 해줘야 할 필요가있을때 사용하면 유용하겠지요?
괄호안에 생성자의 매개변수를 입력하면 되고 형식에 맞는 생성자를 호출하게되는 것은 이전에 생성자 포스팅에서 다룬것과 같습니다. 그러니까 A a = new A("commin");과 this("commin") 은 같은 생성자를 호출하게됩니다. 차이점은 첫번째 객체를 생성하여 생성자를 호출하는것은 새로운 저장공간에 새롭게 만들어진 생성자를 생성하는 것이고 this로 호출한 생성자는 현재 저장공간에서 다시 생성자를 호출하는것입니다.

위에 예제소스의 이해를 돕기위해 플로우를 화살표로 표시해봤습니다.

생성자가 아닌 보통의 메서드를 연속해서 호출해도 같은 원리로 작동되니 순서를 잘 생각하고 코딩해야 합니다. 

1->4 까지는 생성자를 호출하게되고 호출이 끝난 마지막 메서드부터 소스를 읽어내려갑니다. 그러니까 순서가 역순이되는거죠? 

얼핏보면 첫번째 생성자에서 출력되는 data는 name도 없고 address도없고 age도 없을것같지만 결과는 역순으로 차근차근 데이터를 넣고 다시 돌아오게되었기때문에 첫번째 메서드에서 출력되는 내용이 null값이 없는것입니다.

이런식으로 출력이 되죠 ^^

주석에도 언급했듯이 super 예약어는 상속을 배우면서 같이 포스팅하겠습니다.


반응형