static


static이 붙은 멤버변수 (클래스변수)

클래스가 메모리에 올라갈 때 이미 자동적으로 생성되기 때문에, 인스턴스를 생성하지 않아도 사용할 수 있다.

인스턴스를 생성하면 각 인스턴스들은 서로 독립적이기 때문에 서로 다른 값을 유지한다.

각 인스턴스들이 공통적으로 같은 값이 유지되어야 하는 경우에 static을 붙인다. (같은 메모리를 공유)


1
2
3
4
5
6
class Card {
    String kind;    // 카드 무늬 - 인스턴스 변수
    int number;    // 카드 숫자 - 인스턴스 변수
    static int width = 100;     // 카드  폭 - 클래스 변수
    static int height = 250;         // 카드 높이 - 클래스 변수
}
cs

각 Card 인스턴스는 자신만의 무늬(kind), 숫자(number)를 유지해야 하여 인스턴스 변수로 선언하였고

각 카드의 폭(width)과 높이(height)는 모든 인스턴스가 공통적으로 같은 값을 유지해야하므로 클래스 변수로 선언했다.

카드의 폭을 변경해야 할 경우, 모든 카드의 width을 변경하지 않고 한 카드의 width값만 변경해도 모든 카드의 width값이 변경된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class CardTest {
    System.out.println("카드 폭: " + Card.width); // 클래스변수는 객체 생성없이 직접 사용 가능
    System.out.println("카드 높이: " + Card.height); 
 
    Card c1 = new Card();
    c1. kind = "하트";
    c1. number = 7;
    System.out.println("c1의 카드 폭: " + c1.width + " c1의 카드 높이: " + c1.height);
 
    Card c2 = new Card();
    c2. kind = "스페이드"
    c2.number = 4;
    System.out.println("c2의 카드 폭: " + c2.width + " c2의 카드 높이: " + c2.height);
    
    c1.width = 50// 클래스 변수 값을 변경
    c1.height = 80;
 
    System.out.println("c1의 카드 폭: " + c1.width + " c1의 카드 높이: " + c1.height);
    System.out.println("c2의 카드 폭: " + c2.width + " c2의 카드 높이: " + c2.height);
}
cs

결과

카드 폭: 100

카드높이: 250

c1의 카드 폭: 100 c1의 카드 높이: 250

c2의 카드 폭: 100 c2의 카드 높이: 250

c1의 카드 폭: 50 c1의 카드 높이: 80

c2의 카드 폭: 50 c2의 카드 높이: 80



static이 붙은 메서드 (클래스 메서드)

인스턴스 생성없이 호출이 가능하다.


인스턴스 변수는 인스턴스를 생성해야만 존재하기 때문에 static이 붙은 메서드를 호출할 때 

인스턴스가 생성되어 있을 수도 있고, 그렇지 않을 수 있기 때문에 인스턴스 변수의 사용을 허용하지 않는다.

반대로, 인스턴스 변수나 인스턴스 메서드에서는 static이 붙은 멤버들을 사용하는 것이 가능하다.

인스턴스 변수가 존재한다는 것은 static이 붙은 변수가 이미 메모리에 존재한다는 것을 의미하기 때문이다.


메서드 안에서 인스턴스 변수를 필요로 한다면, static을 붙일 수 없지만 

인스턴스 변수를 필요로 하지 않는다면, 가능하면 static을 붙이는 것이 좋다.

static을 안 붙인 메서드는 실행 시 호출되어야 할 메서드를 찾는 과정이 추가적으로 필요하기 때문에 시간이 더 걸린다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MyMath {
    long a, b;
 
    long add() { return a+b; }    // 인스턴스 메서드
    static long add(long a, long b) { return a+b; }    // static 메서드, 인스턴스 변수와 관계없이 매개변수만으로 작업이 가능
}
 
class MathTest {
    public static void main(String args[]){
        // 인스턴스 메서드는 객체 생성 후에 호출이 가능
        MyMath mm = new MyMath();
        mm.a = 200L;
        mm.b = 100L;
        System.out.println("인스턴스 메서드: " + mm.add());
 
        // static 메서드 호출
        System.out.println("static 메서드: " + MyMath.add(200L, 100L));
    }
}
cs

결과

인스턴스 메서드: 300

static 메서드: 300



static이 붙은 블록 (클래스 블록)

클래스 내부에 만들 수 있는 초기화 블록으로, 메서드와 같이 조건문과 반복문 등을 자유롭게 사용할 수 있다.

클래스가 초기화될 때 한번만 실행되고, main() 보다 먼저 수행된다. (MyTest1 예제)

초기화 작업이 복잡해 변수 초기화만으로는 부족한 경우 사용한다. (MyTest2 예제)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyTest1 {
    static {    // static 블록
        System.out.println("static{ }");
    }
 
    {     // 인스턴스 블록
        System.out.println("인스턴스{ }"); 
    }
 
    pulic MyTest1() {
        System.out.println("생성자");
    }
 
    public static void main(String args[]){
        System.out.println("main() 시작");
        MyTest1 mt = new MyTest1();
    }
}
cs

결과

static { }

main() 시작

인스턴스 { }

생성자


1
2
3
4
5
6
7
8
9
10
11
12
13
class MyTest2 {
    static int[] arr = new int[10];
 
    static {    // static 블록
        for(int i=; i<arr.length ; i++){
            arr[i] = i;
        }
    }
 
    public static void main(String args[]){
        System.out.println("arr[1]: " + arr[1]);
    }
}
cs



final


final이 붙은 멤버변수

한 번만 초기화가 가능한 변수이다. 상수를 만들 때 이용한다.


final이 붙은 메서드

오버라이드하거나 숨길 수 없는 메서드이다.


final이 붙은 클래스

상속 계층 구조에서 마지막(final) 클래스인, 상속할 수 없는 클래스로, 확장될 수 없다.


1
2
3
4
5
6
7
final class MyFinal {    // 조상이 될 수 없는 클래스
    final int MAX_SIZE = 10;    // 값을 변경할 수 없는 멤버변수(상수) 
    
    final void getMaxSize() {    // 오버라이딩 할 수 없는 메서드
        return MAX_SIZE;
    }
}
cs



static final

static final을 붙여서, 해당 클래스를 쓸 때 변하지 않고 계속 일관된 멤버 상수로 쓸 것임을 지정한다. 


늘 같은 값을 가질 객체이기 때문에, 

인스턴스를 생성할 때마다 매번 새로 메모리를 잡고 초기화시키지 않고 

한 번만 메모리를 잡고 하나의 메모리 공간을 쓸 수 있게 한다.


예를 들어, 학교 점수 클래스에서 최대 점수를 100으로 만든다면

public static final int MAX_SCORE = 100;

으로 나타낼 수 있다.




참고 출처

http://rockdrumy.tistory.com/214

- 자바의 정석 책

'Java' 카테고리의 다른 글

객체지향 프로그래밍 (Object-Oriented Programming)  (0) 2018.11.26
객체지향 설계  (0) 2018.11.15
직렬화 (Serialization)  (0) 2018.08.04
Overloading (오버로딩)  (0) 2018.07.28
Overriding (오버라이딩, 재정의)  (0) 2018.07.28

+ Recent posts