---------------------------------------------------------------------------------------------------
변수의 static과 메소드의 static은 다르다!!!
---------------------------------------------------------------------------------------------------
1. 변수의 static
- "변수를 저장하는 방법을 static이다" 라는 것!
- 즉, stack의 영역에 저장되어 메소드가 끝이나면 사라지는 변수가 아니라
- method area 영역에 저장되어 메소드가 끝이나더라도 사라지지 않는 변수의 특성을 말한다.
- static 공통적으로 같은 값을 갖고 있고 수정의 필요가 없을 때 사용하므로 보통 final과 함께 쓰이는 경우가 많다.
1.1 장점
- static 키워드를 붙이면 자바는 메모리 할당을 딱 한번만 하게 되어 메모리가 절약된다.
- heap영역이 아니므로 가비지 컬렉터가 수거하지 않고 계속 메모리에 남아있다.
- stack영역이 아니므로 class 또는 instance가 끝남과 동시에 메모리에서 사라지지 않는다.
1.2 단점
- 메모리가 계속 남아있으므로 잘못사용할 시, 메모리가 낭비될 수 있다.
1.3 언제 사용하는가?
- 여러개의 인스턴스가 동일한 값을 저장하는 변수를 갖고 있을 때, static으로 저장한다.
ex) 계산기를 만드는 클래스 Calurlator가 있다면, 각각의 결과값을 저장하는 result라는 변수는 static이 필요하지 않지만,
만약 모든 계산기의 이름이 "카*오"라는 이름을 갖고 있는 것을 저장한다면 static을 이용하여 method area에 저장한다.
1) 그냥 선언할 경우 | 2) static으로 선언할 경우 |
public class Test{ class Calulator{ int result; String calName = "카*오";
void plus(int value){ this.result += value; } } public static void main(String[] args){ Calulator c1 = new Calculator(); Calulator c2 = new Calculator(); } } |
public class Test{ class Calulator{ int result; static String calName = "카*오";
void plus(int value){ this.result += value; } } public static void main(String[] args){ Calulator c1 = new Calculator(); Calulator c2 = new Calculator(); } } |
Calulator로 인스턴스를 만들때마다 heap 영역에 calName이라는 공간이 쌓이게 된다. 만약 Calulator 인스턴스를 100개를 만든다면 100개의 "카*오"라는 동일한 값을 갖는 calName이 생긴다는 것이다 => 메모리낭비 | claName을 static로 선언했으므로 method area영역에 한번만 메모리가 생성되고 만약 Calulator 인스턴스를 100개를 만든다면 하나의 calName을 서로 공유하게 된다 => 메모리 효율적 관리 가능 |
2. 메소드의 static
- 메소드의 static은 어떻게 호출할 것인가 방법에 대한 것.
- 즉, 함수 호출시 클래스로 호출할 것인가 아니면 인스턴스로 호출할 것인가에 문제
- static 메소드의 변수는 메소드가 호출되지 않아도 method area영역에 변수의 메모리가 생성된다.
- static메소드는 메소드를 호출하지 않아도 static 메소드안의 변수와 메소드가 JVM에 올라간다.
- staic이 붙지 않는다면 instance method
2.1 언제 사용하는가?
1) 그냥 선언할 경우 | 2) static으로 선언할 경우 |
public class NomalTest{ public void printTest(){ System.out.println("Instance Method"); } } ----------------------------------------------------------- public class Test{ public static void main(String[] args){ NomalTestc1 = new NomalTest(); //객체 생성 n1.printTest(); } | public class StaticTest{ public static void printTest(){ System.out.println("Static Method"); } } ----------------------------------------------------------- public class Test{ public static void main(String[] args){ StaticTest.printTest(); } } |
|
|
* 2)번 보다는 1)번을 선호한다.
* .java 파일에서 .class로 컴파일 될 때, static 메소드들은 먼저 method area 메모리에 적재된다. 따라서 불필요한 method에 static을 붙일경우,
불필요한 메모리 낭비가 일어날 수 있다.
2.2 main은 왜 반드시 static일까?
main method를 호출하는 명령어는 누구도 존재하지 않는다. 때문에 호출되지 않고도 변수와 method가 JVM에 위치하게 하려면 static이여야 하는 것이다.(static메소드는 메소드를 호출하지 않아도 static 메소드안의 변수와 메소드가 JVM에 생성되므로)
=> 따라서, main은 static을 쓴다!!
그렇다면 다른 method도 전부 static으로 하면 편하지 않을까?
아니다!! 만약, 다른 함수들도 static으로 선언된다면, 모든 method의 변수가 전부 다 JVM에 쌓이고 상주하므로 overflow가 발생하게 된다.
따라서, 적시적소에 static을 붙이는 것이 중요하다.
3. static block
- 클래스가 로딩된 후 클래스 변수를 초기화 하는 용도로 사용
- 클래스 로딩은 단 한 번만 이루어지므로 static 블럭도 단 한번도 실행된다.
- 실행순서: 클래스 로딩 -> 클래스 변수 준비 -> static block 실행
3.1 쉬운 satic block 예시
< 예제코드 >
public class Test45 { //아래의 출력결과를 보면 1, 2사이에 클래스 로딩되었으므로 new를 하려고 할 때 해당 클래스가 없다면 로딩되는 것을 알 수 있다. |
public class ClassA { |
< 출력결과 >
클래스는 언제 로딩될까? => 1 |
4. 첨부
'개발 > Java' 카테고리의 다른 글
[JAVA] 프로그램이 로딩되고 메모리에 쌓이는 순서 (0) | 2017.01.02 |
---|---|
[JAVA] import (0) | 2017.01.01 |
[JAVA] Class(클래스) (0) | 2017.01.01 |
[JAVA] Tip. 코드를 보고 알아보는 if문의 효율정리 (0) | 2017.01.01 |
[JAVA] 제어문 VS 반복문 (0) | 2017.01.01 |