자바의 static 예약어와 static 메서드 활용, 변수의 유효범위, 싱글톤(Singleton)

Yeppi's 개발 일기·2022년 5월 20일
0

JAVA

목록 보기
15/27

1. static 예약어

1) static 이란?

모든 객체가 공유하는 변수

  • 모든 객체가 공유하는 변수
  • 객체에 포함되지 않고, 별도의 메모리 공간에 올라감
  • 메모리를 좀 더 효율적으로 쓰기 위한 것
    • 참조변수로 접근하지 않음
    • 멤버변수에만 사용가능
    • 클래스 이름으로 다이렉트 접근 ⇒ 클래스이름.static변수
    • 객체에 포함되지 않음 ⇒ 따라서 객체 생성하지 않고도 다이렉트 접근 가능
  • 이때, 객체 생성을 덜 하면 좋은 점?
    메모리를 덜쓴다 → 속도가 빨라진다
    👉 성능향상! = 그래서 static 사용



2) 필요성

  • 여러 인스턴스가 공유하는 기준 값이 필요한 경우
  • ex . 학생마다 새로운 학번 생성, 카드 발급할때마다 새로운 카드 번호

👉 매우 번거롭다



3) 프로그램-메모리 저장 방식

저장 흐름

  1. 프로그램 구동
  2. 메모리에 올라감
  3. 메모리에 올라간 상태, 즉 프로세스가 스레드 상태로 동작
  4. 이때, [Data, static, 상수] 영역과 [code] 영역으로 나눠짐
  5. 메모리에서 업로드되는 순간 프로그램 종료

👉 상수 형태로 저장하여, 메모리에서 데이터를 계속 사용할 수 있도록 함


저장 영역

  • 힙(동적) 메모리
    필요할때 로케이션 받아서 쓰고, 다쓰면 릴리즈 시킴

  • 스택 메모리
    함수나 메소드 안에서 쓰는 메모리

  • 데이터 영역
    처음 메모리 로드될때부터 공유되서 쓰다가, 프로그램 업로드 되면 사라지는 메모리

  • 생성자 = 컨스트럭터(constructor)
    객체가 초기화할때 작업은? 생성자에서 함!

👉 static 변수는 인스턴스에서 공통으로 사용하는 영역



2. static 변수

= 클래스 변수 = 정적 변수 (VS 인스턴스 변수)

  • 멤버 변수에만 사용이 가능

  • 인스턴스가 생성될 때 만들어지는 변수가 아닌,
    처음 프로그램이 메모리에 로딩될 때 메모리를 할당하는 변수

  • 인스턴스 생성과 상관 없이 사용 가능 ⇒ 클래스 이름으로 직접 참조

  • static 변수값 변경 시 주의하기
    ❗ 값이 변경되는 순간, 클래스로부터 생성된 모든 객체에 영향 ❗


📌 예시 📌

  • Student 클래스의 static 변수
    static int serialNum;
  • static 변수 참조 방법
    Student.serialNum = 100;


3. static 메서드

1) 개념

  • 객체를 생성하지 않고 클래스 이름으로 직접 호출하여 접근

  • 자주 사용하는 메소드

  • 객체 생성 및 참조 변수로 접근 가능한 일반 멤버변수 → static 메소드에서 사용 불가

  • 즉, 멤버변수와 static 메소드가 같은 클래스에 존재 → 다른 상성을 가진 존재



2) 특징

static 메서드(클래스 메서드)에서는 인스턴스 변수를 사용 불가

  • static 메서드는 인스턴스 생성과 무관하게 클래스 이름으로 호출 가능

    👉 인스턴스 생성 전에 호출 될 수 있으므로, static 메서드 내부에서는 인스턴스 변수를 사용 불가
    👉 생성이 안된 인스턴스 변수를 참조하면 안되기 때문

  • 일반 메소드에서 static 변수 사용가능
    👉 변수가 로드될 때 이미 메모리가 있기 때문

  • static 메소드에서 지역 변수 사용불가
    👉 메소드가 불려질 시점에 메모리에는 해당 변수가 없을 수 도 있기 때문



4. 변수의 유효 범위 & 메모리

  • 변수의 유효 범위(scope)와 생성과 소멸(life cycle)
    → 각 변수의 종류마다 다름

  • 지역변수, 멤버 변수, 클래스 변수
    → 유효범위와 life cycle, 사용하는 메모리도 다름

변수 유형선언 위치사용 범위메모리생성과 소멸
지역변수
= 로컬변수
함수 내부에함수 내부에서만 사용스택- 함수 호출될 때 생성- 함수 끝나면 소멸
멤버변수
= 인스턴스 변수
클래스 멤버 변수로클래수 내부에서 사용
- private 이 아니면, 참조 변수로 다른 클래스에서 사용
- 인스턴스 새성될 때 힙에 생성
- 가비지 컬렉터가 메모리 수거할 때 소멸
static 변수
= 클래스 변수
static 예약어 사용
클래스 내부에
클래스 내부에서 사용
-private 이 아니면, 클래스 이름으로 다른 클래스에서 사용
데이터 영역- 프로그램 처음 시작할 때 상수와 함께 데이터 영역에 생성
- 프로그램 끝날 때 메모리 해제와 함께 소멸

  • static 변수
    → 프로그램이 메모리에 있는 동안(메모리 로드될 때), 계속 그 영역을 차지함(데이터 잡힘)
    ⇒ 너무 큰 메모리를 할당하는 것(한번에 잡아두는 것)은 좋지 않음
    ex. 큰 배열
  • 클래스 내부의 여러 메서드에서 사용하는 변수
    → 멤버 변수로 선언하는 것이 좋음

  • 멤버 변수가 너무 많으면?
    → 인스턴스 생성 시 쓸데없는 메모리가 할당되어 메모리 많이 차지
    ⇒ 상황에 적절하게 변수를 사용해야 함

  • 그렇지만, 멤버변수 안쓰면?
    → 쓸때마다 함수간 매개변수 전달해야됨, 귀찮🤦
    ⇒ 클래스의 속성이 될 수 있는 애들도 적당히 사용하기 ❗

  • 모든 static 변수라고 private 는 아님
    → 인스턴스간 공유할 필요가 있는 값에 대해서는 public 으로 하면 됨


5. static 블록

1) 개념

  • static 블록으로 지정된 코드는 클래스 파일이 로딩되는 순간 가장 먼저 실행
	static {
		// 가장 먼저 실행
	}


2) 📌 실습 📌

  • 클래스로부터 하나의 객체만 생성하여 공유할 수 있음
public class Student {
	public static String school = "냥냥이 대학교";
	String name;
	public static Student instance;
	
	static {
		if(instance == null) {
			studentInstance = new Student("yeppi"); // 하나의 객체 생성
		}
	}
	
	private Student(String name) {
		this.name = name;
	}
	
	public void studentInfo() {
		System.out.println(name + "의 학교는 " + Student.school);
	}
}
  • 그런데, 생성자가 private 으로 막혀 있어서 Student 객체 생성 못할 때. . .

  • static 블록에서 Student 객체를 생성하여 static 변수인 instance 에 할당


  • main 에서 실행
		Student a = Student.instance;
		System.out.println(a.toString());
		a.printInfo();
		
		Student b = Student.instance;
		System.out.println(b.toString());
		b.printInfo();
		
		Student c = Student.instance;
		System.out.println(c.toString());
		c.printInfo();

출력결과

static1.Student@149852f9
yeppi의 학교는 냥냥이 대학교
static1.Student@149852f9
yeppi의 학교는 냥냥이 대학교
static1.Student@149852f9
yeppi의 학교는 냥냥이 대학교

👉 세 개의 참조변수가 참조하는 객체의 주소가 모두 동일한 것을 확인할 수 있다!



6. static 응용 '싱글톤 패턴'

1) 개념

  • 프로그램에서 인스턴스가 단 한 개만 생성되어야 하는 경우 사용하는 디자인 패턴

  • static 변수와 메서드를 활용하여 구현

  • 유일한 객체를 제공할 때 사용



2) 싱글톤 객체 구현

  • 생성자는 private으로 선언
    private Studnet() {}

  • 클래스 내부에 유일한 private 인스턴스 생성
    private static Studnet instance = new Studnet();

  • 외부에서 유일한 인스턴스를 참조할 수 있는 public 메서드 제공

public static Studnet getInstance() {
		
	if( instance == null) {
		instance = new Studnet();
	}
	return instance;
		
}


3) 싱글톤 패턴 표현식

  • 클래스이름
  • 멤버변수
  • 생성자와 메서드
    - → private
    + → public

싱글톤의 자세한 개념이나 실습은
디자인 패턴 시리즈 2번 싱글톤 링크를 참고해주세요


profile
imaginative and free developer. 백엔드 / UX / DATA / 기획에 관심있지만 고양이는 없는 예비 개발자👋

0개의 댓글