Java(this, static)
this
객체 내부에서는 인스턴스 멤버(필드, 메소드)에 접근하기 위해 사용함.
생성자와 메소드의 매개변수명이 인스턴스 멤버인 필드명과 동일한 경우, 인스턴스 필드임을 강조하고자 할때 사용함.
this의 3가지 사용방법 1. this 는 자기 자신을 가리킨다.(인스턴스의 주소) 2. 생성자에 다른 생성자를 호출할 때 사용할 수 있다. 3. 자신의 주소(참조값, 주소값)를 반환시킬 수 있다. |
this. 및 this()를 활용하자.
public class Person {
private String name; // 변수 + 데이터 타입 + 멤버변수
private int age;
private String phone;
private String gender;
// 생성자
public Person(String name, int age) { // () = 지역변수
this.name = name; // 자기 자신의 멤버 변수 name에 외부에서 들어오는 지역 변수 name을 대입한다.
this.age = age;
}
public Person(String name, int age, String phone) {
this(name, age); // 생성자에서 다른 생성자를 호출할 수 있다. this(...)
this.phone = phone; // 다른 생성자를 가장 먼저 호출하고 나머지 수식을 작성해야 한다.
}
public Person(String name, int age, String phone, String gender) {
this(name, age, phone);
this.gender = gender;
}
// getter
public Person getPerson() {
return this; // 자신의 주소값을 반환시킨다.
}
public void showInfo() {
System.out.println("이름 : " + name + ", 나이 : " + age); // this 생략 가능
}
// setter
public void setName(String name) {
this.name = name;
}
테스트 파일을 생성하여 주소값을 확인하자.
public class PersonTest {
public static void main(String[] args) {
// main함수 안의 변수 = 지역변수
Person person1 = new Person("홍길동", 100);
Person personBox = person1; // person1이 personBox에 담김
Person personBox2 = person1.getPerson();// Person.java의 getPerson을 호출해서 자신의 주소값을 가짐.
// heap 메모리에 생성된 person1의 주소값을 personBox, personBox2가 같은 객체의 주소값을 가짐.
Person personLee = new Person("이순신", 101);
System.out.println("------------------------");
// 위 코드까지는 heap 메모리 영역에 객체가 2개 생성된 상태이다.
// 지역변수인 person1, personBox, personBox2는 같은 객체를 가리킨다.
// name을 홍길동 -> 티모로 바꾸기
personBox.setName("티모");
person1.showInfo();
}// end of main
}// end of class
final 키워드
어떤 필드에 final을 붙이면 상수가 된다.
클래스 변수는 모든 객체가 공유하는 정보를 나타낸다.
static을 붙여 클래스 변수로 만들어서 공유하는 것이 메모리 공간을 절약한다.
(상수를 인스턴스 변수로 선언하면 각 객체마다 하나씩 만들어 지므로 저장 공간이 낭비된다.)
final 필드 와 상수 선언 = 값을 변경하는 것을 막고 읽기만을 허용
final 필드에 초기값 주는 방법 2가지 1. 필드 선언 시에 초기값 대입 2. 생성자에서 초기값 대입 |
예시)
static final int ZEALOT = 1; // 상수는 대문자로
final int MARINE = 2;
final int ZERGLING = 3;
final int GAME_END = 0;
정적 멤버(static) 변수
클래스의 모든 인스턴스가 공유할 수 있는 변수
객체가 동일한 static 변수의 값을 공유함
클래스 변수라고 하며, 클래스 이름 뒤에 . 연산자로 접근할 수 있다.
객체마다 가지고 있을 필요성이 없는 공용적인 필드는 정적 필드로 선언하는 것이 좋다.
예시를 보자.
번호표를 뽑아주는 기계를 클래스 파일로 생성한다.
public class NumberPrinter {
private int id;
public static int waitNumber; //접근 제어 지시자 + static + 데이터 타입 + 변수
// 생성자
public NumberPrinter(int id) {
this.id = id;
waitNumber = 1;
}
// 기능 -- 번호표를 출력한다.
public void printWaitNumber() {
System.out.println(id + "번에 기기의 대기 순번은 " + waitNumber);
waitNumber++;
}
}
* static은 클래스 당 하나만 생성된다.
테스트 클래스를 생성한다.
public static void main(String[] args) {
NumberPrinter n1 = new NumberPrinter(1);//왼쪽
NumberPrinter n2 = new NumberPrinter(2);//오른쪽
n1.printWaitNumber(); // 고객1
n1.printWaitNumber(); // 고객2
n1.printWaitNumber(); // 고객3
n1.printWaitNumber(); // 고객4
n2.printWaitNumber(); // 고객5
n2.printWaitNumber(); // 고객6
}
}
NumberPrinter 번호 뽑는 기계 객체를 2개 형성하였다.
NumberPrinter 변수명에 .연산자를 통해 NumberPrinter 클래스의 PrintWaitNumber 기능을 호출하였다.
정적멤버(static) 사용
public static void main(String[] args) {
System.out.println(NumberPrinter.waitNumber);
}
main 함수에 클래스 명(NumberPrinter). waitNumber 를 작성한다.
데이터 타입 int에 값을 초기화하지 않았기 때문에 기본값인 0이 출력된다.
정적 멤버(static) 메소드(클래스 메소드)
접근 제어 지시자 + static + 데이터 타입 + 메소드명() 의 형태를 띄며, 메소드명() 메소드는 정적 메소드로 선언되고 클래스명을 통해 호출한다.
public static void main(String[] args) { }
main() 메소드 앞에 static 이 있는 이유
: 자바 가상 기계가 객체를 생성할 필요 없이 main() 메소드를 호출할 수 있도록 하기 위함이다.
정적 메소드 안에는 정적 메소드 호출 가능
예시를 보자.
main() 메소드는 정적 메소드라서 메소드 안에 인스턴스 메소드 출력 시 컴파일 오류가 발생한다.
public static void main(String[] args) {
add(10, 20); // 오류 : 정적 메소드 안에서 인스턴스 메소드 호출함
}
int add(int x, int y) {
return x + y;
}
그러므로 호출하고자 하는 메소드는 인스턴스 메소드가 아닌 정적 메소드를 작성해야 한다.
public static void main(String[] args) {
add(10, 20); // 정적 메소드 안에서 정적 메소드 호출 가능함.
}
static int add(int x, int y) { // 정적 메소드
return x + y;
}