요르딩딩

Static 이란 본문

[Java]

Static 이란

요르딩딩 2022. 1. 26. 14:43
728x90
반응형

< static 변수 >

  • 예를 들어 다음과 같은 HouseKim 클래스가 있다.
class HouseKim {
    String lastname = "김";
}

public class Sample {
    public static void main(String[] args) {
        HouseKim kim1 = new HouseKim();
        HouseKim kim2 = new HouseKim();
    }
}
  • 위와 같이 클래스를 만들고 객체를 생성하면 각각의 객체에 대해 lastname을 저장하기 위해 메모리가 별도로 할당된다
  • 만약 lastname이 항상  "김" 이여야 한다면 static을 사용하여 메모리의 이점을 얻을 수 있다.

 

class HouseKim {
    static String lastname = "김";
}

public class Sample {
    public static void main(String[] args) {
        HouseKim kim1 = new HouseKim();
        HouseKim kim2 = new HouseKim();
    }
}
  • 장점 : static 키워드를 붙이면 자바는 메모리 할당을 딱 한번만 하게 되어 메모리 사용에 이점이 있다.
  • 사용 : 항상 변하지 않는 변수인 경우 static으로 선언하여 사용한다.
  • final  키워드 : lastname값이 변경되지 않기를 바란다면, static 앞에 final을 붙이면 된다. (한번 설정되면 변경 불가)

 

  • static은 공유 개념을 이용해 사용할 수 도 있다.
  • static 으로 설정하면 같은 곳의 메모리 주소만을 바라보기 때문에 static 변수의 값을 공유하게 되는 것이다.
class Count  {
    int count = 0;
    Counter() {
        this.count++;
        System.out.println(this.count);
    }
}

public class Sample {
    public static void main(String[] args) {
        Count c1 = new Count();
        Count c2 = new Count();
    }
}

위 Count 클래스를 실행하면 다음과 같은 결과값이 나온다.

1
1

 

  • static을 붙여보자
class Count  {
    static int count = 0;
    Counter() {
        this.count++;
        System.out.println(this.count);
    }
}

public class Sample {
    public static void main(String[] args) {
        Count c1 = new Count();
        Count c2 = new Count();
    }
}

위 Count 클래스를 실행하면 다음과 같은 결과값이 나온다.

1
2
  • static 변수는 메모리를 한번만 할당하기 때문에, 객체가 여러번 생성되었더라도 한번만 할당된 메모리를 사용하기에 공유 개념도 되는것이다.

< static 메소드 >

class Count  {
    static int count = 0;
    Count() {
        count++;
        System.out.println(count);
    }

    public static int getCount() {
        return count;
    }
}

public class Sample {
    public static void main(String[] args) {
        System.out.println(Count.getCount());  // 스태틱 메서드는 클래스를 이용하여 호출
    }
}
    • Count 클래스에 getCount() 라는 static 메소드가 추가되었다.
    • 스태틱 메소드 안에서는 객체변수 접근이 불가능 하다. 위 예에서는 count 변수가 static 변수이기 때문에 스태틱 메소드(static method)에서 접근이 가능하다.
    • 메소드 앞에 static 키워드를 붙이면 Count.getCount() 와 같이 객체 생성없이 클래스를 통해 메서드를 직접 호출할 수 있다.
    • 객체 생성없이 클래스를 통해서 메서드를 직접 호출하므로 Utillity성 메소드를 작성할 때 많이 사용된다.

< 싱글톤 패턴(Singleton Pattern) >

  • 싱글톤은 하나의 객체만을 생성하게 강제하는 패턴이다.
  • 즉 클래스를 통해 생성할 수 있는 객체는 한 개만 되도록 만드는 것이 싱글톤이다.
class Singleton {
    private Singleton() {
    }
}

public class Sample {
    public static void main(String[] args) {
        Singleton singleton = new Singleton();  // 컴파일 오류가 발생한다.
    }
}
  • 위와 같은 코드를 작성하면 컴파일 에러가 발생한다.
  • 왜냐하면 Singleton 클래스의 생성자에 private 키워드로 다른 클래스에서 Singleton 클래스의 생성자로의 접근을 막았기 때문이다.이렇게 생성자를 private 으로 만들어 버리면 다른 클래스에서 Singleton 클래스를 new 를 이용하여 생성할 수 없게 된다.
  • new를 이용하여 무수히 많은 객체를 생성한다면 싱글톤의 정의에 어긋나기 때문이다. 그래서 일단 new로 객체를 생성할 수 없도록 막은 것이다.
class Singleton {
    private static Singleton singleton;
    private Singleton() {
    }

    public static Singleton getInstance() {
        if(singleton==null) {
            singleton = new Singleton();
        }
        return one;
    }
}

public class Sample {
    public static void main(String[] args) {
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();
        System.out.println(singleton1 == singleton2);  // true 출력
    }
}
  • 최초 getInstance가 호출 되면 singleton이 null이므로 new에 의해서 객체가 생성이 된다.
  • 이렇게 한번 생성이 되면 singleton은 static 변수이기 때문에 그 이후로는 null이 아니게 된다.
  • 그런 후에 다시 getInstance 메소드가 호출되면 이제 one은 null이 아니므로 이미 만들어진 싱글톤 객체인 one을 항상 리턴한다.
  • 위에서 예제로 든 싱글톤은 Thread Safe 하지는 않다. 쓰레드 환경에서도 안전한 싱글톤을 만드는 방법은 이곳에 어울리지 않으므로 생략한다.

 

  • 정리 : static은 메모리에 한번만 할당한다는 개념이 제일 중요한거 같다.
  • 그렇기에 static 변수는 객체 생성을 여러번해도 같은 값을 사용할 수 있고, 그게 또 공유하는 개념도 되는거 같다.
  • 싱글톤 패턴도 이와 같은 논리이다. 
  • 다만,  static 메소드의 경우는 static 메소드안에서 static 변수만 사용할 수 있다는 점과 객체생성없이 클래스를 통해서 메소드를 호출할 수 있다는 점을 알아두자.

참고 : https://wikidocs.net/228#static_1

 

 

728x90
반응형
Comments