Java static 키워드
- static은 '정적인, 움직이지 않는다'라는 뜻으로 메모리에 고정된다.
그래서 모든 인스턴스에 접근할 수 있도록 공유가되고
클래스 차원에서 정의된 필드 하여 'class field'라고 한다.
그러므로 static 키워드를 이요하면 객체를 생성하지 않고도 변수나 함수를 사용할 수 있다.
- static area는 클래스가 메모리에 로딩되면서 static도 같이 올라가고, 프로그램이 종료되면 JVM에서 해당 메모리를 반환한다.
- static은 메모리할당이 한 번만 이루어진다.
static 키워드의 사용범위
1. 모든 인스턴스에 공통적으로 사용해야 할 경우 static을 붙인다.
- 인스턴스를 생성하면, 서로 독립적이기 때문에 서로 다른 값을 유지하므로 각 인스턴스들이 공통값을 유지하기 위해서는 static을 사용한다.
2. static 키워드가 붙은 멤버변수나 메서드는 인스턴스(객체화)를 생성하지 않아도 사용할 수 있다.
- static 변수와, 메서드는, 클래스가 메모리에 올라갈 때 자동으로 생성된다.
3. static이 붙은 메서드에서는 인스턴스 변수(not static)를 사용할 수 없다.
4. 메서드 내에서 인스턴스 변수를 사용하지 않는다면 static을 사용하는 것을 고려한다.
- 메서드 작업하면서 인스턴스 변수가 필요 하다면 static을 사용할 수 없지만,
인스턴트 변수가 필요 없다면 static을 사용한다. 왜냐하면 메서드 호출시간이 짧기때문에 효율성이 좋아지기 때문이다.
1) static 멤버 변수
ex_) 멤버변수에 static 키워드가 붙으면 인스턴스화 를 하지 않고 사용가능하다.
public class B {
static int count = 0;
int cnt = 0;
public B() {
count++;
cnt++;
System.out.println("static B : "+count);
System.out.println("B : "+cnt);
}
public static void main(String[] args) {
B b1 = new B();
B b2 = new B();
B b3 = new B();
}
}
결과는 count는 3 cnt= 1이다.
count는 static 변수라 메모리가 공유되어 있어서 증가가 되지만
cnt는 b1,b2,b3가 각각 새로운 클래스 인스턴스화 되어 메모리 영역이 다르다.
2) static 메서드
ex_) static 메서드도 메모리가 먼저 올라가기 때문에 인스턴스화 할 필요가 없다.
public class E {
int e=3;
static int r =4;
public static void e() {
System.out.println("hello");
//e=4; (e는 인스턴스 변수이므로 클래스 인스턴스화를 해야 사용가능하다)
new E().e=4;
r =5; //static 변수이므로 사용가능
}
public static void main(String[] args) {
E.e();
}
}
static 변수는 static 메서드에서 사용가능하지만
인스턴스 변수는 static 메서드에서 사용 불가능하다.
3) static 클래스(nested class)
ex_) static class는 외부클래스에서 사용이 안되고 inner class에서 만 사용할 수 있다.
아래 singleton 처럼 LazyHolder inner 클래스에 static 키워드를 이용하면
Singleton 객체가 없이도 LazyHolder객체를 참조할 수 있다.
public class Singleton {
int e=5;
private Singleton() {
System.out.println("hello");
}
private static class LazyHolder {
private static final Singleton SINGLETON = new Singleton();
}
public static Singleton getInstance() {
return LazyHolder.SINGLETON;
}
}
4) static 블록
ex_) static 블록은 클래스를 로드할 때 단 한번만 사용된다.
public class B {
public static int count =0;
public int c=0;
static {
count++;
System.out.println("B satic block1 : "+count);
}
public B() {
count++;
System.out.println("B : "+count);
}
{
count++;
System.out.println("normal block : "+ count);
}
static {
count++;
System.out.println("B static blokc2 : "+ count);
}
public static void BBB() {
System.out.println("B");
}
public static void main(String[] args) {
C b1 = new C();
C b2 = new C();
C b3 = new C();
}
}
public class C extends B{
static {
count++;
System.out.println("C static block : "+ count);
}
public C() {
count++;
System.out.println("C :"+ count);
}
{
count++;
System.out.println("C normal block : "+ count);
}
}
결과
B satic block1 : 1
B static blokc2 : 2
C static block : 3
normal block : 4
B : 5
C normal block : 6
C :7
normal block : 8
B : 9
C normal block : 10
C :11
normal block : 12
B : 13
C normal block : 14
C :15
결과를 보면 알듯이
static block는 로딩시 한번만 실행되지만
일반 블록은 클래스가 인스턴스화 될때마다 수행된다.
'Language > Java' 카테고리의 다른 글
String 보다는 StringBuilder, StringBuffer를 사용해야하는 이유. (0) | 2016.10.07 |
---|---|
[링크]셧다운 후크를 사용한 어플리케이션의 안전한 종료 처리 (0) | 2016.08.11 |
java final 키워드 (0) | 2016.08.11 |
쓰레드 (0) | 2016.05.25 |
[NIO] 파일 채널(FileChannel) (0) | 2016.04.06 |