this 키워드 (레퍼런스 / 생성자)
📍 this 키워드
– 자신의 인스턴스 주소값을 저장하는 참조 변수.
→ 개발자가 생성하는 것이 아니라 Java에 의해 자동으로 생성됨.
– 모든 인스턴스 내에는 this가 존재하며, 자신의 인스턴스 주소가 저장됨.
→ 즉, 인스턴스 마다 this에 저장된 값이 다름.
▶ 레퍼런스 this( )
– 자신의 인스턴스 내의 멤버에 접근 (멤버변수 or 멤버메서드)
– 주로, 로컬변수와 인스턴스(멤버) 변수의 이름이 같을 때, 인스턴스 변수를 지정하는 용도로 사용.
→ this키워드가 붙은건 해당 클래스의 멤버를 뜻함.
▸ 기본 문법
this.인스턴스 변수
this.메서드( )
– 자신의 클래스 내의 생성자 또는 메서드 내에서 위와 같은 형태로 접근.
– 로컬변수와 멤버변수를 구별하기 위해서,
멤버변수 앞에 레퍼런스 this를 사용하여 해당 인스턴스에 접근하는 코드로 사용해야 함.
외부에서 멤버변수 name에 접근 | 내부에서 멤버변수 name에 접근 |
참조변수명.name | this.name |
EX1 )
• 클래스 생성하기
class Person{
// 인스턴스(멤버) 변수
private String name;
private int age;
// 파라미터 생성자 정의
public Person(String name, int age) {
this.name = name;
this.age = age;
}
– 레퍼런스 this = Person 클래스 안에 있는 멤버변수 name.
– 로컬변수와 인스턴스(멤버)변수의 이름이 같을 때 인스턴스 변수를 지정하는 용도로 사용되므로,
파라미터로 받은 로컬 변수의 값을 인스턴스 변수에 저장함.
// get & set 메서드 정의 (name)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
// name = name;
// this가 없으면 로컬변수 name을 다시 로컬변수 name에 저장하는 코드가 됨.
}
1. get 메서드
– 로컬변수와 멤버변수 이름이 중복되지 않음(로컬변수 존재X) → 레퍼런스 this 생략 가능.
– 클래스의 멤버변수 name을 뜻하므로 return this.name; 과 동일함.
2. set 메서드
– 메서드 내의 로컬변수(String name)와 클래스 내의 멤버변수(name)의 이름이 동일하므로
메서드 내에서 변수 지정 시, 로컬변수가 지정됨.
→ 따라서 클래스의 멤버변수인 name에 레퍼런스 this 키워드를 붙여 자신(클래스)의 멤버변수임을 구분함.
– 클래스의 멤버변수 name은 setName() 메서드의 파라미터, 즉 로컬변수 name값을 멤버변수 name에 저장하는 코드.
// get & set 메서드 정의 (age)
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 메서드 정의
public void showPersonInfo() {
System.out.println("이름 : " + name);
System.out.println("나이 : " + age);
}
} // Class Person
• main 메서드에서 실행하기
Person p = new Person("홍길동", 20);
p.showPersonInfo();
– Person 클래스에서 정의한 파라미터 생성자와 showPersonInfo() 메서드가 실행되어 출력됨.
✓ 실행 결과
이름 : 홍길동
나이 : 20
// p.name = "이순신"
// 접근제한자가 private이므로 접근 불가
// set 메서드 사용
p.setName("이순신");
p.setAge(44);
p.showPersonInfo();
– 클래스의 멤버변수 접근제한자가 private이므로 참조변수를 통한 접근 불가능 → set 메서드 사용
– set 메서드 사용으로 파라미터로 전달된 값이 클래스의 멤버변수에 저장되고,
showPersonInfo() 메서드에 의해 출력문이 출력됨.
✓ 실행 결과
이름 : 이순신
나이 : 44
EX2 )
• Account 클래스 생성하기
class Account{
// 멤버변수(인스턴스 변수)
private String accountNo;
private String ownerName;
private int balance;
// 파라미터 생성자
public Account(String accountNo, String ownerName, int balance) {
this.accountNo = accountNo;
this.ownerName = ownerName;
this.balance = balance;
}
– 인스턴스 변수와 로컬 변수 이름이 동일하므로, 인스턴스 변수(좌변) 앞에 레퍼런스 this를 (this.xxx) 붙여서 구별해줌.
// get & set 메서드
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
public String getOwnerName() {
return ownerName;
}
public void setOwnerName(String ownerName) {
this.ownerName = ownerName;
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
// showAccountInfo() 메서드
public void showAccountInfo() {
System.out.println("계좌번호 : " + accountNo);
System.out.println("예금주명 : " + ownerName);
System.out.println("현재잔고 : " + balance + "원");
}
}
• main 메서드에서 실행하기
Account acc = new Account("123-4567-8910", "김아무개", 10000);
acc.showAccountInfo();
– 파라미터로 전달된 값이 파라미터 생성자의 레퍼런스 this로 전달되어 클래스의 멤버변수에 저장됨.
– showAccountInfo() 메서드가 실행되어 해당 출력문이 출력됨.
✓ 실행 결과
계좌번호 : 123-4567-8910
예금주명 : 김아무개
현재잔고 : 10000원
▶ 생성자 this( )
– 자신의 생성자 내에서 자신의 또 다른 생성자를 호출할 때 사용함.
– 레퍼런스 this사용과 동일하게 자신의 인스턴스에 접근하여, 다른 오버로딩 생성자를 호출하는 용도로 사용됨.
– 생성자 오버로딩 시, 인스턴스 변수에 대한 초기화 코드가 중복되는데, 초기화 코드 중복을 제거하는 용도로 사용.
→ 여러 생성자에서 각각 인스턴스 변수를 중복으로 초기화하지 않고 하나의 생성자에서만 초기화 코드를 작성한 뒤,
나머지 생성자에서 해당 초기화 코드를 갖는 생성자를 호출하여 초기화 할 값만 전달 후,
대신 인스턴스 변수 초기화를 수행함.
→ 메서드 오버로딩 시 코드 중복을 제거하기 위하여 하나의 메서드에서만 작업을 수행하고,
나머지 메서드는 해당 메서드를 호출하여 데이터를 전달하는 것과 동일함.
(단, 메서드는 이름( )으로 호출, 생성자는 this( )로 호출하는 차이)
▸ 호출 기본 문법
this([파라미터 데이터 ]);
– 생성자 내의 첫번째 라인에 작성함.
– 자신의 생성자 내에서 다른 오버로딩된 생성자를 호출 하는 방법.
EX )
• 클래스 생성하기
class MyDate{
int year;
int month;
int day;
// 기본 생성자
public MyDate() {
this(1900, 1, 1);
– 연도=1900, 월=1, 일=1로 초기화 함.
– 자신의 생성자 내에서 다른 오버로딩된 생성자 호출
→ public MyDate(int year, int month, int day) { } 생성자가 호출됨.
– 다른 실행 코드보다 무조건 먼저 실행되어야 함.
→ 무조건 생성자 내의 첫번째 라인에 작성.
System.out.println("MyDate() 생성자 호출");
year = 1900;
month = 1;
day = 1;
}
– 인스턴스 변수 초기화 코드가 다른 생성자와 중복됨.
– 중복 제거를 위해 3개의 모든 값을 전달받는 파라미터 생성자를 호출하고,
초기화에 사용될 데이터를 전달하여 대신 초기화를 수행함.
→ 코드 중복 제거 가능.
// 연도(year)만 전달, 나머지는 1월 1일로 초기화하는 생성자
public MyDate(int year) {
this(year, 1, 1);
System.out.println("MyDate(int) 생성자 호출");
}
– MyDate(int, int, int) 생성자를 호출하여, 전달받은 연도(year)와 1월 1일 값을 전달하여 초기화.
// 연도(year) & 월(month)을 전달, 나머지는 1일로 초기화하는 생성자
public MyDate(int year, int month) {
this(year, month, 1);
System.out.println("MyDate(int, int) 생성자 호출");
}
– MyDate(int, int, int) 생성자를 호출하여, 전달받은 연도(year)와 월(month)과 1일 값을 전달하여 초기화 함.
// 모든 인스턴스 변수 데이터를 전달받아 초기화 하는 생성자
public MyDate(int year, int month, int day) {
System.out.println("MyDate(int, int, int) 생성자 호출");
this.year = year;
this.month = month;
this.day = day;
}
} // Class MyDate
– 모든 인스턴스 변수의 데이터를 전달받아 초기화 하는 생성자가 생성자 this에 해당함.
• main 메서드에서 실행하기
MyDate d1 = new MyDate();
System.out.println(d1.year + "/" + d1.month + "/" + d1.day);
MyDate d2 = new MyDate(2023);
System.out.println(d2.year + "/" + d2.month + "/" + d2.day);
MyDate d3 = new MyDate(2023, 3);
System.out.println(d3.year + "/" + d3.month + "/" + d1.day);
MyDate d4 = new MyDate(2023, 3, 7);
System.out.println(d4.year + "/" + d4.month + "/" + d4.day);
✓ 실행 결과
MyDate(int, int, int) 생성자 호출
MyDate() 생성자 호출
1900/1/1
MyDate(int, int, int) 생성자 호출
MyDate(int) 생성자 호출
2023/1/1
MyDate(int, int, int) 생성자 호출
MyDate(int, int) 생성자 호출
2023/3/1
MyDate(int, int, int) 생성자 호출
2023/3/7