course 2021/JAVA

day14 - static

코딩하는토끼 2021. 9. 7. 23:51

> 정적제한자 static

사용제한자 usage level modifier - 정적제한자 static

변수, 메소드에 적용

static 변수/메소드는 해당 클래스 객체생성 없이도 "클래스명.이름"으로 참조 가능

static 블록 안에서 static 변수/메소드만 사용 가능, non-static 멤버는 객체생성없이 참조 불가

static은 지정된 변수/메소드를 객체와 무관하게 만들어주므로 this 불가

1. static field (정적 변수)

- 모든 객체들이 값 공유 (공유변수)

- 해당 클래스 객체생성 없이 "클래스명.변수명"으로 참조 가능 (클래스 변수)

//Count 클래스 
public class Count {
    public int a;  //일반 변수
    public static int b;  //정적 변수 
    
    //멤버변수는 생성과 동시에 기본값으로 자동 초기화됨
}

//Main 클래스
public class MainClass {
    public static void main(String[] args) {
        Count c1 = new Count();  //첫번째 객체생성 c1
        c1.a++;  //1
        c1.b++;  //1
        
        System.out.println(c1.a); //1
        System.out.println(c1.b); //1
        
        Count c2 = new Count();  //두번째 객체생성 c2
        c2.a++;  //c1.a 와 다른 새로운 a이므로 1
        c2.b++;  //정적 변수 - 모든 객체들이 값을 공유하는 공유 변수, c1.b와 같은 변수이므로 2
        
        System.out.println(c2.a); //1
        System.out.println(c2.b); //2
        
        Count.b++;  //정적변수는 객체생성 없이 "클래스이름.변수명"만으로도 참조가능 //3
        
        System.out.println(c1.b); //3
        System.out.println(c2.b); //3
        System.out.println(Count.b); //3
        //c1.b 와 c2.b 와 Count.b 모두 같은 변수
    }
}

2. static method (정적 메소드)

- 해당 클래스 객체생성 없이 "클래스명.메소드명()"으로 참조 가능

- static 블록 안에서 static 멤버만 사용 가능, non-static 멤버는 객체생성없이 참조 불가

- static 변수라도 선언은 불가

- non-static 메소드로 오버라이딩 불가

- ex. main(), Math.random(), Arrays.toString(), Integer.parseInt()

//Count 클래스
public class Count {
    public int a;
    public static int b;
    
    public static int doIt() {  //doIt 메소드 - 반환유형 int, 매개변수 없음
        //return ++a; //non-staic 멤버 사용 불가
        return ++b;
    }
}

//Main 클래스 
public class MainClass
    public static void main(String[] args) {
        //정적메소드는 객체생성없이 "클래스명.메소드명()"만으로도 참조가능
        System.out.println(Count.doIt()); //1
        System.out.println(Count.doIt()); //2
        System.out.println(Count.doIt()); //3
    }
}

3. static initializer (정적 초기화자)

static 에 단순히 블록을 사용한 경우

static 변수 초기화 역할 (static 변수가 객체생성 없이 사용되면 생성자를 통한 초기화가 불가하므로)

클래스가 로딩 시 생성자/main메소드에 앞서 단 한번 실행됨 - 한번만 실행되어야하는 로직을 이곳에 기술하여 사용

//StaticInit 클래스
public class StaticInit {
    static{  //static initializer 정적 초기화자
        System.out.println("static initializer 가 실행됨");
    }
    
    public StaticInit() {
        System.out.println("생성자 호출됨");
    }
}

//Main 클래스
public class MainClass {
    public static void main(String[] args) {
        
        StaticInit s1 = new StaticInit();
        System.out.println(s1);
        
        StaticInit s2 = new StaticInit();
        System.out.println(s2);
    }
}

//static initializer 가 실행됨  //s1 정적초기화자 단 한번 실행됨
//생성자 호출됨  
//staticpac.StaticInit@15db9742  //주소
//생성자 호출됨  //s2
//staticpac.StaticInit@6d06d69c

 

싱글톤 패턴 singleton pattern

어떤 클래스의 객체가 오직 하나임을 보장 & 이 객체에 접근할 수 있는 전역적인 접촉점 제공

클래스 객체를 하나만 생성하고 모든 곳에서 이 객체에 접근하게 하여 전역의 개념으로 객체 사용할 수 있음

객체의 생성을 제한하기 위해 사용