객체를 생성하지 않고도 클래스 이름으로 접근할 수 있으며, 모든 객체가 공유하는 값 또는 기능을 표현하는 데 사용됨 → 클래스 자체에 속하는 멤버
Static
은 '정적인, 고정된'이라는 의미를 갖고 있는데 이것은 객체에 소속되는 것이 아닌, 클래스에 고정되어 있다는 뜻이다.
객체를 생성해서 가져다가 쓰는것이 아닌 클래스 내부에 있는 static을 직접 가리키는 것으로 이해했다.
이 그림을 보면 Method Area(Static Area)
가 있는데 이 영역에 static
이 붙은 메소드나 변수들이 저장된다. static
말고도 초기에 필요한 정보들 패키지 클래스
, 인터페이스
, 상수
, final
등이 로드된 후에 메모리에 항상 상주하고 있다! 그런데 여기에 할당되면 끝날때까지 Garbage Collector
에 수거되지 않기 때문에 메모리 낭비가 발생할 수도 있다.
수업때 배운 내용같은데 기억이 가물가물하네..
위에서 말했다시피 static
이 붙은 변수나 메소드들은 시작하자마자 메모리가 할당되고, 인스턴스에 소속된 것이 아니라 클래스에 소속되었기 때문에 값이 공유된다.
보통 인스턴스를 만들어서 변수를 건들면 다른 인스턴스에는 영향이 없는데 static
변수를 건들면 다른 인스턴스에서도 값이 바뀌어서 나온다. 그 예시는 아래에 코드로 설명해보겠다!!
이제 코드로 살펴보겠따
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
라는 클래스를 만들어서 클래스변수인 nonStaticNum
과 static
변수인
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; // 에러!
}
}
일단 StaticTest1
과 StaticTest2
객체를 생성해줬다.
그 다음 바로 인스턴스 변수인 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
에 대해서 알아봤다. 다음시간에는 원시값 포장에 대해서 알아보자!
참고사이트
생활코딩