Static이란?

허준기·2023년 5월 2일
1

자바

목록 보기
4/9

Static

 객체를 생성하지 않고도 클래스 이름으로 접근할 수 있으며,
모든 객체가 공유하는 값 또는 기능을 표현하는 데 사용됨 
→ 클래스 자체에 속하는 멤버

Static은 '정적인, 고정된'이라는 의미를 갖고 있는데 이것은 객체에 소속되는 것이 아닌, 클래스에 고정되어 있다는 뜻이다.

객체를 생성해서 가져다가 쓰는것이 아닌 클래스 내부에 있는 static을 직접 가리키는 것으로 이해했다.

  1. 메모리에 고정적으로 할당
  2. → 각 객체들에서 공통적으로 하나의 값이 유지되어야 할 경우 사용
  3. 객체 생성 없이 사용
  4. → 클래스 이름 뒤에 메소드나 변수를 붙여 사용
  5. 프로그램이 시작되면 메모리의 static 영역에 적재 → 프로그램이 종료될 떄 해제
  6. 이 그림을 보면 Method Area(Static Area)가 있는데 이 영역에 static이 붙은 메소드나 변수들이 저장된다. static 말고도 초기에 필요한 정보들 패키지 클래스, 인터페이스, 상수, final 등이 로드된 후에 메모리에 항상 상주하고 있다! 그런데 여기에 할당되면 끝날때까지 Garbage Collector에 수거되지 않기 때문에 메모리 낭비가 발생할 수도 있다.
    수업때 배운 내용같은데 기억이 가물가물하네..

    위에서 말했다시피 static이 붙은 변수나 메소드들은 시작하자마자 메모리가 할당되고, 인스턴스에 소속된 것이 아니라 클래스에 소속되었기 때문에 값이 공유된다.

    보통 인스턴스를 만들어서 변수를 건들면 다른 인스턴스에는 영향이 없는데 static 변수를 건들면 다른 인스턴스에서도 값이 바뀌어서 나온다. 그 예시는 아래에 코드로 설명해보겠다!!

  7. static 메소드 내에서 인스턴스 변수 사용 불가능
  8. → 프로그램 실행과 동시에 메모리에 올라가기 때문에 인스턴스 변수 사용 불가능!

이제 코드로 살펴보겠따

class StaticTest {
    public int nonStaticNum = 0;
    public static int staticNum = 0;

    public void plusNonStaticNum() {
        nonStaticNum++;
    }

    public void plusStaticNum() {
        staticNum++;
    }

    public static void printStaticNum(){
        System.out.println(staticNum);
    }
}

StaticTest라는 클래스를 만들어서 클래스변수인 nonStaticNumstatic 변수인
staticNum을 만들어줬다.
그리고 메소드는 plusNonStaticNum()plusStaticNum() 를 클래스 메소드로 만들어주고 static 메소드인 printStaticNum()까지 만들어줬다.
이제 메인을 보자!

public class Static {
    public static void main(String[] args) {
        StaticTest StaticTest1 = new StaticTest();
        StaticTest StaticTest2 = new StaticTest();
        System.out.println(StaticTest1.nonStaticNum);	// 0
        System.out.println(StaticTest2.nonStaticNum);	// 0
        StaticTest1.plusNonStaticNum();
        System.out.println(StaticTest1.nonStaticNum);	// 1 
        System.out.println(StaticTest2.nonStaticNum);	// 0
		
        StaticTest1.plusStaticNum();
        System.out.println(StaticTest.staticNum);	// 1

        StaticTest2.plusStaticNum();
        System.out.println(StaticTest.staticNum);	// 2

        StaticTest.printStaticNum();	// 2
        
        //StaticTest1.staticNum;		// 에러!
        //StaticTest2.staticNum;		// 에러!
    }
}

일단 StaticTest1StaticTest2 객체를 생성해줬다.
그 다음 바로 인스턴스 변수인 nonStaticNum을 출력해주면 둘다 0이 나온다. 이제 StaticTest1 에만 plusNonStaticNum() 메소드를 동작해주고 다시 nonStaticNum을 출력하면 StaticTest1 은 1이 출력되는데 StaticTest2는 0이 출력된다. 그 이유는 각 인스턴스의 변수가 바뀌기 때문에 서로 영향을 주지 않기 때문이다.

이제 static 을 살펴보자. StaticTest1 인스턴스에서 plusStaticNum() 메소드를 동작하고 staticNum을 출력하면 staticNum에서 1이 출력된다. 그 다음 StaticTest2 인스턴스에서도 plusStaticNum() 메소드를 동작하고 출력해주면 staticNum 이 2로 출력된다. 그 이유가 뭘까???

그건 바로 static 변수들은 클래스 소속이기 때문에 값을 공유하기 때문이다!!!!!!
객체에 들어있는 변수들은 그 객체 안에서 바꿨을때만 변하지만 static변수들은 바꾸면 클래스에 붙어있는 변수가 바뀐다. 그래서 StaticTest.printStaticNum(); 을 했을 때도 변경된 2가 출력되는 것이다. 참고로 printStaticNum() 메소드는 static 메소드이기 때문에 객체가 생성되기 전에도 사용이 가능하다.

마지막으로 객체를 통해 static 메소드를 사용하려고 하면 오류가 난다.

그 이유는 인스턴스가 특정 객체가 아닌 클래스에 속하기 때문이다. 정적 메소드는 인스턴스에 속하지 않기 때문에 인스턴스에서 사용할 수 없는것이다!!!

지금까지 static 에 대해서 알아봤다. 다음시간에는 원시값 포장에 대해서 알아보자!

참고사이트
생활코딩

코딩팩토리

점프 투 자바

기록하는 개발자

profile
나는 허준기

0개의 댓글