(공감과 댓글 하나는 글쓴이에게 큰 힘이 됩니다.)

 

변수나 메소드에 static이라는 예약어가 붙으면 각각 클래스 변수와 클래스 메소드가 된다. 인스턴스가 생성될 때만 사용 가능한 인스턴스 변수, 인스턴스 메소드와는 다르게 클래스가 정의만 되어도 접근해서 사용이 가능하다.

 

 

■ static 변수(클래스 변수)

- 딱 한번만 정의되어 모든 인스턴스에서 공유되는 변수이다. 프로그램이 실행될 때 생성돼서 프로그램이 종료될 때 GC(Garbage Collector)에 의해 소멸된다. 인스턴스의 생성 여부에 상관없이 메모리에 올라가므로 클래스 변수라고도 하며, 클래스의 이름으로 접근할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Employee {
    public static int employeeCount;
        
    public Employee() {
        ++employeeCount;
    }
}
 
public class Main {
    public static void main(String[] args) {
        Employee e1 = new Employee();
        System.out.println(e1.employeeCount); // 1
        System.out.println(Employee.employeeCount); // 1
        
        Employee e2 = new Employee();
        System.out.println(e1.employeeCount); // 2
        System.out.println(Employee.employeeCount); // 2
    }
}
cs

Line 2 : static 변수 employeeCount 선언

Line 4 ~ Line 6 : 디폴트 생성자 (static 변수 employeeCount의 값을 1 증가)

Line 11 : 인스턴스 생성

Line 12 : 참조 변수를 이용한 employeeCount 출력

Line 13 : 클래스를 이용한 employeeCount 출력

Line 16 : 참조 변수를 이용한 employeeCount 출력

Line 17 : 클래스를 이용한 employeeCount 출력

 

■ static 메소드(클래스 메소드)

- static 변수와 동일한 방식으로 호출하게 되며, static 메소드가 삽입된 클래스의 모든 인스턴스로부터 접근이 가능하다. static 메소드 안에서는 인스턴스 변수의 사용이 불가능하다. (static 메소드는 프로그램의 시작과 동시에 메모리에 올라가는데, 인스턴스 변수는 인스턴스가 생성됐을 때 메모리에 올라가므로 참조가 불가능)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Employee {
    private static int employeeCount;
    private int temp;
 
    public static int getEmployeeCount() {
        return employeeCount;
    }
 
    public static void setEmployeeCount() {
        // temp = 1;
        ++employeeCount;
    }
}
 
public class Main {
    public static void main(String[] args) {
        System.out.println(Employee.getEmployeeCount()); // 0
        Employee.setEmployeeCount();
        System.out.println(Employee.getEmployeeCount()); // 1
    }
}
cs

Line 2 : static 변수 employeeCount를 private으로 선언 (getter, setter를 통한 접근만 가능)

Line 3 : 멤버 변수 temp 선언

Line 5 : static 변수 employeeCount의 값을 얻어오기 위한 get 메소드

Line 9 : static 변수 employeeCount의 값을 설정하기 위한 set 메소드

Line 10 : static 변수와 static 메소드는 인스턴스의 생성에 상관없이 메모리에 올라가는데, 인스턴스 변수인 temp는 인스턴스가 생성되는 경우에 메모리에 올라간다. static 메소드를 메모리에 올리기 전에 인스턴스의 생성이 불가능하기 때문에 해당 부분은 에러가 발생한다.

Line 17 : static 메소드를 호출 employeeCount의 값 출력

Line 18 : static 메소드를 호출하여 employeeCount의 값 1 증가

Line 17 : static 메소드를 호출 employeeCount의 값 출력

'Java' 카테고리의 다른 글

자바(Java) 다차원 배열  (0) 2020.07.04
자바(Java) 배열(Array)  (0) 2020.07.04
자바(Java) this 예약어  (0) 2020.07.03
자바(Java) 접근 제어자  (0) 2020.06.30
자바(Java) 생성자(Constructor)  (0) 2020.06.30

(공감과 댓글 하나는 글쓴이에게 큰 힘이 됩니다.)

 

자바에서 this는 생성된 인스턴스 스스로를 가리키는 예약어이다.

 

■ this를 통한 멤버 변수 참조

- this 예약어를 통해 멤버 변수임을 명시할 수 있다. this를 사용하지 않더라도 IDE에서 자동으로 구분을 해주지만, this를 사용하여 명시해주면 개발자가 해당 변수를 더 쉽게 파악할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Calculator {
    private int num1;
    private int num2;
    
    public Calculator(int num1, int num2) {
        this.num1 = num1;
        this.num2 = num2;
    }
}
 
public class Main {
    public static void main(String[] args) {
        Calculator calc = new Calculator(1020);
    }
}
cs

Line 2 : 멤버 변수 num1 선언

Line 3 : 멤버 변수 num2 선언

Line 5 : num1과 num2를 받아오는 생성자

Line 6 : 멤버 변수 num1을 생성자 선언 시 넘겨준 num1의 값으로 초기화

Line 7 : 멤버 변수 num2를 생성자 선언 시 넘겨준 num2의 값으로 초기화

 

■ this를 통한 다른 생성자 호출

- this를 통해 생성자에서 다른 생성자를 호출할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Calculator {
    private int num1;
    private int num2;
    private char ch;
    
    public Calculator(int num1, int num2) {
        this.num1 = num1;
        this.num2 = num2;
        System.out.println("Calculator(int num1, int num2)");
    }
    
    public Calculator(int num1, int num2, char ch) {
        this(num1, num2);
        this.ch = ch;
        System.out.println("Calculator(int num1, int num2, char ch)");
    }
}
 
public class Main {
    public static void main(String[] args) {
        System.out.println("------------ calc1 ------------");
        Calculator calc1 = new Calculator(1020); // Calculator(int num1, int num2)
        
        System.out.println("------------ calc2 ------------");
        Calculator calc2 = new Calculator(1020'+'); // Calculator(int num1, int num2)
                                                        // Calculator(int num1, int num2, char ch)
    }
}
cs

Line 6 : num1과 num2를 받아오는 생성자

Line 12 : num1, num2, ch를 받아오는 생성자

Line 13 : Line 6의 생성자를 호출하여 num1과 num2를 초기화

Line 14 : 멤버 변수 ch 초기화

Line 22 : num1, num2를 매개변수로 전달하는 Line 6의 생성자 호출

Line 25 : num1, num2, ch를 매개변수로 전달하는 Line 12의 생성자 호출

 

■ this를 통한 자신의 주소 반환

- this를 통해 자기 자신의 주소 값을 반환할 수 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Calculator {
    private int num1;
    private int num2;
    
    public Calculator(int num1, int num2) {
        this.num1 = num1;
        this.num2 = num2;
    }
    
    public Calculator printAddress() {
        return this;
    }
}
 
public class Main {
    public static void main(String[] args) {
        Calculator calc1 = new Calculator(1020);
        System.out.println(calc1.printAddress()); // Calculator@15db9742
    }
}
cs

Line 10 : 자기 자신의 주소 값을 반환하는 메소드 (반환형을 클래스형으로 만들어야 함)

Line 18 : 생성한 calc1 인스턴스의 주소 값 출력

(공감과 댓글 하나는 글쓴이에게 큰 힘이 됩니다.)

 

지시자 클래스 내부 동일 패키지 상속받은 클래스 이외의 영역
private O X X X
default O O X X
protected O O O X
public O O O O

 

■ 정보 은닉

- 변수를 private으로 선언하는 경우 다른 클래스에서 이를 직접 참조할 수 없다. 따라서 getter, setter라고 불리는 get(), set() 메소드를 통해 private 변수의 값을 설정하거나 가져와야 하는데, 이렇게 직접 접근하지 못하고 getter, setter로 접근하도록 숨겨 놓는 것을 정보 은닉이라고 한다. 단순히 변수에 직접 대입하여 사용하는 경우 양수만 사용해야 되는 상황에서 음수를 사용했을 때 컴파일러가 에러를 인지하지 못해 문제 상황을 인지하지 못할 수도 있다. 하지만 setter 메소드에서 변수 값을 대입하는 경우 조건문을 통해 판단하여 에러 상황을 처리해 줄 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Calendar {
    private int month;
 
    public int getMonth() {
        return month;
    }
 
    public void setMonth(int month) {
        if(month >= 1 && month <= 12) {
            this.month = month;
        } else {
            System.out.println("잘못된 값을 입력하셨습니다!");
            return;
        }
    }
}
 
public class Main {
    public static void main(String[] args) {
        Calendar calendar1 = new Calendar();
        calendar1.setMonth(1);
        
        Calendar calendar2 = new Calendar();
        calendar2.setMonth(13); // 잘못된 값을 입력하셨습니다!
    }
}
cs

Line 2 : 정수형 변수 month를 private으로 선언

Line 4 ~ 6 : month의 값을 얻어오기 위한 get 메소드

Line 8 ~ Line 15 : month의 값을 설정하기 위한 set 메소드 (month 값에 따른 조건 분기)

Line 20 : 인스턴스 생성

Line 21 : 참조 변수 calendar1의 month를 1로 설정

Line 23 : 인스턴스 생성

Line 24 : 참조 변수 calendar2의 month를 2로 설정 (범위에 벗어난 값을 입력하여 메시지 출력 후 종료)

+ Recent posts