자바에서 This

2025. 4. 15. 21:22JAVA/JAVA 기초 문법

🖥️ This란?

this는 현재 객체 자기 자신을 가리키는 키워드로, 생성된 인스턴스의 메모리 주소를 가진다.

자바에서 모든 인스턴스 메서드는 실행될 때 해당 인스턴스를 참조하는 레퍼런스를 내부적으로 가지고 있는데,

이 참조가 바로 this다.

 

❓ 꼭 this가 필요할까?

public class Dog {
    private String name;
    
    public Dog(String name) {
        this.name = name; // 왼쪽은 필드, 오른쪽은 파라미터
    }
}

 

생성자 파라미터와 인스턴스 필드의 이름이 같을 때,

this.name 이 없으면 컴파일러는 지역변수 name 인식하게 된다.

즉, this는 지역 변수와 구분해주는 키워드

 

⌨️ This 사용 되는 주요 상황

this 사용 사용 목적
1. 멤버 변수와 지역 변수(파라미터) 이름이 같을 때 변수 이름 충돌 방지
2. 현재 객체를 다른 메서드나 생성자에 전달할 때 자기 자신을 넘김
3. 생성자에서 다른 생성자를 호출할때 ( this(...) ) 생성자 코드 재사용
4. 내부 클래스에서 외부 클래스 객체를 참조할 때 ( Outer.this ) 외부 인스턴스에 접근
5. 메서드 체이닝을 위해 자신을 반활할 때 연결된 메서드 호출 가능

 🖱️ 멤버 변수와 파라미터 이름이 같을 때

public class Dog {
    private String name;
    
    public Dog(String name) {
        this.name = name; // 필드와 파라미터 이름이 같을 때 구분
    }
}

 

💥 만약 여기서 this 키워드를 사용하지 않으면 Shadowing문제 발생!!

 

☁️ 쉐도잉이란? 

내부 범위의 변수(지역 변수 또는 파라미터)가 외부 범위의 변수(주로 필드)를 가리는 현상

즉, 같은 이름의 변수가 가까운 범위에 선언되어 있어서 바깥쪽 변수를 가려버리는 현상을 쉐도잉이라 한다.

public class Dog {
    private String name; // 클래스의 필드
    
    public Dog(String name) { // 파라미터가 필드와 이름이 같음    
     // 필드name = 파라미터name   
        name = name; // this가 없으면 필드에 값을 못 넣음
    }
}

 

  • 파라미터 name이 필드 name을 가려버림(쉐도잉)
  • 그래서 this.name을 사용해서 필드라고 명확하게 알려줘야 함!!

🖱️ 현재 객체를 메서드에 전달할 때

this는 현재 실행 중인 메서드를 호출한 객체 자신을 가리키기 때문에,메서드를 호출할 때, 그 메서드에게 "나 자신"을 넘겨줄수 있는 방법이다.

public class Dog {
    
	    String name;

	    public Dog(String name) {
	        this.name = name;
	    }

	    // 소개하기 메서드: 자기 자신(this)을 다른 메서드에 전달
	    public void introduce() {
	        // 현재 이 객체 자신을 메서드에 전달함
	        DogInfo(this);
	    }

		// Dog 정보를 출력하는 메서드
	    public void DogInfo(Dog dog) {
	        System.out.println("이름: " + dog.name);
	    }
	
	    public static void main(String[] args) {
	        Dog dog1 = new Dog("강아지");
	         dog1.introduce();  // 자기 자신을 메서드에 전달
	    }
	    
}

❗ 현재 객체를 넘길때 this를 사용하는 이유

이유 설명
유연한 코드 흐름 다른 메서드나 클래스에 객체를 넘겨 협력할 수 있음
설계의 일관성 메서드 호출 흐름을 자연스럽게 연결함

🖱️ 생성자에서 다른 생성자를 호출할 때 

public class Dog {
    private String name;
    private int gender;
    private int age;
    
    // 기본 생성자
    public Dog () {} 
    
    // name만 받는 생성자
    public Dog(String name) { 
        this.name = name;
    }
    
    // name, gender 받는 생성자
    public Dog(String name, int gender) {
        this(name);            // 위의 name만 받는 생성자 호출
        this.gender = gender;
    }
    
    // name, gender, age 받는 생성자
    public Dog(String name, int gender, int age) {
        this(name, gender);    // 위의 name, gender 생성자 호출
        this.age = age;
    }

❗ 이 패턴을 쓰는 이유

장점 설명
중복 제거 같은 초기화 코드가 여러 생성자에 있을 때 재활용 가능
유지보수 관리 기본값, 로직 변경 시 한 군데만 수정하면 됨
가독성 ↑ 흐름이 명확하고 구조적임

🖱️ 내부 클래스에서 외부 클래스 객체를 참조할 때 

내부 클래스에서 this는 기본적으로 내부 클래스의 인스턴스를 가리킨다.이떄 외부 클래스 객체를 참조하고 싶을 때 외부클래스명.this 형식으로 접근한다.

public class Outer {
    private String outerField = "Outer Field";

    public class Inner {
        private String innerField = "Inner Field";

        public void printFields() { 
            System.out.println(innerField);            // 내부 클래스의 필드
            System.out.println(this.innerField);       // 내부 클래스의 필드
            System.out.println(Outer.this.outerField); // 외부 클래스의 필드
        }
    }

    public void createInner() {
        Inner inner = new Inner();
        inner.printFields();
    }
}

❗ Outer.this를 쓰는 이유

내부 클래스는 외부 클래스의 모든 멤버에 접근할 수 있다.
하지만 내부와 외부에 동일한 이름의 변수가 있을 때 명확하게 구분하기 위해 Outer.this를 사용한다.

 

만약 이름이 겹친다면?

public class Outer {
    String value = "Outer";

    class Inner {
        String value = "Inner";

        void show() {
            System.out.println(value);            // Inner
            System.out.println(this.value);       // Inner
            System.out.println(Outer.this.value); // Outer
        }
    }
}

 

만약 필드 이름이 겹친다면, Outer.this.value를 통해 외부 클래스의 멤버를 가리킬 수 있다.

 

💥 static 내부 클래스에서는 this 사용불가

static class Inner {
    void test() {
        // Outer.this ← 사용 불가! 컴파일 에러
    }
}
  • static 내부 클래스는 외부 인스턴스에 종속되지 않기 때문에, this 사용 불가

🖱️ 메서드 체이닝을 위해 자신을 반활할 때

this를 return해서 자기 자신을 반환하면, 메서드를 연달아 호출할 수 있다.

이걸 메서드 체이닝(Method Chaining)라 한다.

 

왜 this를 반환해야 할까?

자바에서 객체의 메서드를 연속적으로 호출하려면,

각 메서드가 객체 자신을 다시 리턴해야 그 다음 메서드도 호출 가능하다.

object.doSomething().doNextThing().doFinalThing();

 

즉, 이걸 가능하게 하려면, 각 메서드가 this를 return 해야 한다.

public class Dog {
    
	    String name;
	    int age;

	    public Dog setName(String name) {
	        this.name = name;
	        return this; // 현재 객체 자신 반환
	    }

	    public Dog setAge(int age) {
	        this.age = age;
	        return this; // 현재 객체 자신 반환
	    }

	    public Dog introduce() {
	        System.out.println("이름: " + this.name + ", 나이: " + this.age);
	        return this; // 계속 이어질 수 있도록 반환
	    }
}

❗ 체이닝에서 this를 사용하는 이유

이유 설명
this를 반환 다음 메서드 호출이 가능하게 함
자연스러운 연결 코드가 읽기 쉽고 직관적
자기 자신을 계속 넘김 상태 변경 후 자기 자신을 유지

 

🎯 정리 🎯

상황 예시 설명
변수 이름 겹침 this.name = name; 멤버 변수와 지역 변수 구분
객체 전달 someMethod(this); 현재 객체 자신을 다른 메서드에 넘김
생성자 호출 this(...); 같은 클래스 내 다른 생성자 호출
메서드 체이닝 setOnClickListener(this); 자기 자신을 콜백으로 등록
외부 클래스 참조 Outer.this 내부 클래스에서 외부 객체 참조

 

✅ this는 객체 자신을 대표하는 키워드이자, 객체지향 언어(OOP)에서 나 자신을 명확하게 드러내는 유일한 방법이다

✅ 자바에서 this는 "지금 이 코드를 실행하고 있는 바로 그 객체 자신"을 말한다.

'JAVA > JAVA 기초 문법' 카테고리의 다른 글

Operators (연산자)  (0) 2025.04.30
Array(배열)  (0) 2025.04.23
Constructor (생성자)  (0) 2025.04.14
Access Modifier(접근 제어자)  (0) 2025.04.04
변수(Variable) 필드(Field) 객체(Object)  (0) 2025.04.04