어제 #103 Java ++연산자에서 ++연산자는 확실하게 알았고

 오늘은 static에 대해서 알아보려고 한다

 

 

 static이란

 - 정적키워드

 - 객체를 생성하지 않고도 변수나 함수를 사용할 수 있다

 - static이 붙은 변수(클래스변수)는 클래스가 메모리에 올라갈 때 이미 자동적으로 생성되기 때문이다

 - 객체를 생성하지 않아도 되니까 빠르고 편리하다

 

 

 

 어떠한 경우 static을 사용하는지

 - 클래스를 설계할 때 멤버변수 중 모든 인스턴스에 공통적으로 사용 및 공유하는 경우

 - 각 인스턴스들이 공통적으로 같은 값이 유지되어야하는 경우

 - 어떤 메서드가 인스턴스가 생성되지 않았더라도 호출할 것이라면, 메서드 내에서 인스턴스 변수를 사용하지 않는다면 static을 붙이는 것을 고려한다

 

 

 

 하지만 static 사용을 지양한다고 하는데

 

 객체지향적이지 않다

 - 객체를 생성하지 않고도 변수나 함수를 사용하고 공유되는 static은 추론과 테스트가 힘들다

 - 이는 각 객체의 데이터들이 캡슐화되어 객체들간의 상호작용을 통해 로직을 구성하는 객체 지향 프로그래밍의 원칙에 위반되고 객체지향의 관점에서 static은 좋은 코드라고 얘기하기 힘들다

 

 메모리 문제

 - 인스턴스 생성시 인스턴스들은 Heap 영역에 생성되어 Garbage Collector을 통해 메모리를 관리받는다

 - 즉, 함수 호출이 끝난 후 인스턴스는 소멸되고 메모리를 절약하게된다

 - 하지만 static은 프로그램이 실행되는 내내 살아있게 되고 작업을 끝내더라도 Garbage Collector에 의해 메모리가 회수되지 않는다

 

 재사용성이 떨어진다

 - static 메서드(클래스메서드)는 interface를 구현하는데 사용될 수 없고 이는 재사용성을 높여주는 객체지향적 기능들을 사용하는 것을 방해한다

 

 

 

 코드를 보면 더 확실하게 알 수 있다

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package kr.or.ksmart;
 
public class Static {
    
    public int a = 20;
    static int b = 0;
    
    public static void main(String[] args) {
        
        int a = 10;
        Static.b = 10;
        
        Static st = new Static();
        
        System.out.println(Static.b++); //10, 객체를 생성하지 않아도 사용할 수 있다
        System.out.println(st.b); //11, 클래스 변수는 공유되는 것을 확인할 수 있다
        System.out.println(a); //10
        System.out.println(st.a); //20
        
    }
}
 
 

 

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.test;
 
public class MemberCall {
    
    int iv1 = 10// 인스턴스 변수(non-static field)
    static int cv1 = 20// 클래스 변수(static field)
    
    int iv2 = cv1;
    
    //static int cv2 = iv1; 
    //Cannot make a static reference to the non-static field iv1
    //클래스 변수는 인스터스 변수를 참조할 수 없다
    
    static int cv2 = new MemberCall().iv1; //사용하려면 객체를 생성해야 한다
    
    static void classMethod1() {
        
        System.out.println(cv1 + " <-- cv1 classMethod1() MemberCall.java");
        
        //System.out.println(iv1);
        //Cannot make a static reference to the non-static field iv1
        //클래스메서드에서 인스턴스 변수를 바로 참조할 수 없다
    
        MemberCall mc = new MemberCall();
        System.out.println(mc.iv1 + " <-- mc.iv1 classMethod1() MemberCall.java");
    }
    
    void instanceMethod1() {
        System.out.println(cv1 + " <-- cv1 instanceMethod1() MemberCall.java"); 
        System.out.println(iv1 + " <-- iv1 instanceMethod1() MemberCall.java"); //인스턴스 메서드에서는 인스턴스 변수를 참조할 수 있다
    }
 
    static void classMethod2() {
        classMethod1();
        
        //instanceMethod1();
        //Cannot make a static reference to the non-static method instanceMethod1() from the type MemberCall
        //클래스 메서드에서는 인스턴스 메서드를 바로 호출할 수 없다
        
        MemberCall mc = new MemberCall();
        mc.instanceMethod1(); //인스턴스를 생성한 후 인스턴스 메서드 호출 가능하다
    }
 
    void instanceMethod2() {
        classMethod1();
        instanceMethod1();
    }
}
 

 

 

 

 

 

 

출처 : https://vaert.tistory.com/101

 

[Java] Static 키워드 바로 알고 사용하자

자바를 한번쯤 공부해본사람이라면 static키워드를 모르지는 않을 것입니다. 하지만, 바르게 알고 있는 사람들은 그리 많지 않습니다. 자바경력자를 면접볼 때 static키워드에 대해서 질문하곤 합니다. 면접관 :..

vaert.tistory.com

출처 : https://unabated.tistory.com/entry/%EC%99%9C-%EC%9E%90%EB%B0%94%EC%97%90%EC%84%9C-static%EC%9D%98-%EC%82%AC%EC%9A%A9%EC%9D%84-%EC%A7%80%EC%96%91%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94%EA%B0%80

 

왜 자바에서 static의 사용을 지양해야 하는가?

자바에서 데이터를 가공하거나 특정 메서드를 수행할 때 새로운 클래스를 만들어서 이를 인스턴스화 해서 쓸건지 아니면 static 으로 쓸건지 고민하게 될 때가 있다. 사실 후자는 객체지향적 관점에서 그리 좋은..

unabated.tistory.com

 

'교육 > Java' 카테고리의 다른 글

#113 Java MVC 패턴, model1과 model2  (0) 2019.10.28
#107 Java 싱글톤 패턴  (0) 2019.10.18
#103 Java ++ 연산자  (0) 2019.10.14
#101 Java 2차원 배열 알고리즘  (0) 2019.10.10
#93 Java Connection Pool  (0) 2019.09.26

+ Recent posts