땀이 삐질삐질 나는 개발 일기

Android,Java의 this는 언제, 어떻게 쓰일까? 본문

개발 Tip

Android,Java의 this는 언제, 어떻게 쓰일까?

삐질 2019. 5. 21. 21:03
안녕하세요. 삐질삐질 개발하는 개발자 삐질입니다.

오늘은 우리가 안드로이드 또는 자바 개발자라면 쉽게 볼수 있지만, 정확한 의미를 모른 채로 사용하는 

"this" 키워드에 대해 알아보도록 하겠습니다.

먼저 단순히  this라는 키워드는,  아래와 같은 직관적인 뜻을 가집니다.


자, 어려울게 없죠??  즉 내 스스로의 Object를 가르키게 됩니다. 
실제로는 Object의 주소값을 가르쳐요. ( 편의상 그냥 Object로만 말씀드릴게요)

우리가 흔히 사용하는 방식은 아래와 같습니다.
public class MainActivity extends AppCompatActivity implements CallbackTest<String>,View.OnClickListener {

    Button button;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.button = this.findViewById(R.id.btn);
        this.button.setBackgroundColor(Color.parseColor("#ffffff"));
        this.button.setOnClickListener(this);

        TestClass testClass = new TestClass();
        testClass.setCallbackTest(this);


    }

    @Override

    public void result(String object) {

        Log.d("Test Callback", "Test");
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id){
            case R.id.btn:
                break;
        }
    }

    public static class TestClass {
        CallbackTest callbackTest;
        String testString;

        public void setCallbackTest(CallbackTest callbackTest) {
            this.callbackTest = callbackTest;
        }

        public void setTestString(String testString) {
            this.testString = testString;
        }
    }
}
부분 부분 뜯어서 살펴봅시다. 


  • 나 스스로 Object를 참조하면, 당연히 Object 속에 선언되어 있는 멤버 인스턴스에 접근은 기본이죠?
this.button = this.findViewById(R.id.btn);
this.button.setBackgroundColor(Color.parseColor("#ffffff"));
this.button.setOnClickListener(this);



여기까지는 이해가 되는데, 문제가 있습니다.

"TestClass에서 CallbackTest인터페이스가 파라미터로 선언 돼 있는데, 왜 MainActivity에서 this로해?? 
멤버 변수도 선언 되어있지 않은데?? 뭐 어떤걸 전달하는지 어떻게 아는 거야?" 라고 물을 수 있습니다.

실제로 제가 오픈 커뮤니티에서 질문 답변 활동을 하며 굉장히 많이 받는 질문 중 하나입니다.
implement와 this의 정확한 의미를 알지 못하고 두루뭉술하게 알고있기 때문이죠.

  • implement로 인터페이스를 Mainactivity에서 상속하게 되면서, 부모  Interface를 상속  -> 부모 Interface에 있는 메서드를 자식에게 재정의 하게 됩니다.
  • 자식 클래스인 MainActivity는 부모인 CallbackTest Interface의  Object를 상속받게되는 것이죠.
  • 이에 따라, public void setCallbackTest(CallbackTest callbackTest)  이 코드에서  부모의 CallbackTest Object가 자연스럽게 전달되는 것이죠.
    TestClass testClass = new TestClass();
    testClass.setCallbackTest(this);
}

@Override

public void result(String object) {

    Log.d("Test Callback", "Test");
}
public static class TestClass {
CallbackTest callbackTest;
String testString;

public void setCallbackTest(CallbackTest callbackTest) {
this.callbackTest = callbackTest;
}

public void setTestString(String testString) {
this.testString = testString;
}
}



여기까지 이해가 되셨다면, 다들 적어도 한번 쯤은 아래와 같은 경험이 있으실 겁니다.


왜 그런지 아시겠나요? 






맞습니다. 바로 new View.OnClickListener()라는  Object 속에서의 this이기 때문에
이때의 this는 MainActivity의 Object를 가르키는것이 아니기때문입니다. 계층 구조상 Mainactivity가 상위에 있지만,
실제로는 가장 하위에있는 new View.OnClickListener의 Object를 가르키게 되는 것이죠.


이를 해결하기 위해서는  아래와같이 코드를 작성할 수 있습니다.

요약하자면, new View.OnClickListener 내부의 this가 가르키는 범위는  new View.OnClickListener이지 MainActivity.class 가
아니게됩니다.

이처럼 영향을 미치는 범위를 “Scope”라고 하는데, 
쉽게 말하면, {} 안에 선언 된 변수의 영향범위는 해당 {}이게 됩니다.

"this"의 개념과  “Scope의 개념을 명확하게 구분한다면, 다른 코드를 작성 함에 있어서도
좀더 명확하게 이해하고 코드를 작성할 수 있게 되실 겁니다.






안드로이드 초보 개발자를 위해 아래와 같은 카카오 오픈톡을 운영 중입니다. 


Comments