일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- KEVISS
- StringBuilder
- DI
- 조합
- java
- Spring
- jpa
- 열 속성
- SQL
- jwt
- lambda
- static
- DDL
- equals
- 재정의
- hashcode
- Test
- 바이너리 카운팅
- docker
- 필드 주입
- 테스트 코드
- MSA
- redis
- cache
- 생성자 주입
- AOP
- VUE
- 인덱스
- stream
- select_type
- Today
- Total
백엔드 개발자 블로그
STATIC 본문
static 키워드란?
- 애플리케이션 생성 시 최초에 한번만 메모리에 올려 재사용이 가능하다.
- 이미 메모리에 적재 되었으므로 인스턴스 생성 없이 사용 가능하다.
- 동기화 이슈가 있을 수 있으므로 가변적인 상태 보단 불변적인 상태를 유지 하는게 좋다.
- 공통적인 특성이나 기능을 사용하는 용도로 유틸성으로 많이 사용된다.
static 적용 범위
클래스(Class)
주로 내부 클래스에 static을 붙인다. 외부 클래스의 인스턴스 생성없이 내부 클래스를 접근하기 위한 용도이다.
public class StaticCar {
static String _where="I am a Car from Germany!";
Country _country; // object of inner class country
StaticCar(){
_country=new Country(); // instantiate the inner class
}
static class Country { // static member inner class
String showCountry() {
return _where;
}
}
public static void main(String[] args) {
StaticCar myCar = new StaticCar() ; // instantiated object of class StaticCar
System.out.print("Access through an Country reference");
System.out.println(" created in an object of a StaticCar:");
System.out.println(myCar._country.showCountry());
// instantiated object of class StaticCar.Country
StaticCar.Country country = new StaticCar.Country();
System.out.println("Access through an Country reference that is local:");
System.out.println(country.showCountry());
}
}
그렇다면 static 내부 클래스의 인서턴스를 여러 개 생성할 경우, 다 동일한가?
public static void main(String[] args) {
// instantiated object of class StaticCar.Country
StaticCar.Country country = new StaticCar.Country();
StaticCar.Country country2 = new StaticCar.Country();
System.out.println(country == country2);
}
정답은 false이다.
내부 클래스에 static을 붙였다는 의미는 단순히 외부 클래스의 인스턴스 인스턴스 생성 없이 내부 클래스의 인스턴스를 생성할 수 있는지에 초점을 맞추는 것이다. class에는 static을 붙인다고 해서 인스턴스도 하나만 생성된다고 생각하면 안된다.
외부에 static을 붙인 경우는?
IDE에서 오류가 발생할 것이다. 그것은 단순히 static을 붙인것에 큰 의미가 없기 때문이다.
변수(Variable)
static을 선언하여 인스턴스 생성없이 해당 변수를 사용할 수 있다. static을 붙일 경우엔 보통 final 키워드를 혼합하여 불변을 보장하도록 사용하는 것을 권장한다. static만 붙였을 경우엔 생성자에서 초기화가 가능하지만 final을 혼합할 경우엔 생성자에서 초기화 할 수 없고 초기값을 지정해야 한다.
public class StaticFruit {
private static int seeds; // 초기값이 0으로 설정됨
public StaticFruit(int seeds) {
this.seeds = seeds;
}
}
public class StaticFruit {
private final int seeds; // 인스턴스 변수라 인스턴스 생성시 결정됨
public StaticFruit(int seeds) {
this.seeds = seeds;
}
}
public class StaticFruit {
private static final int seeds = 2; // 불변이며 static 변수라 초기값을 지정해 주어야 한다.
public StaticFruit() {}
}
함수(Method)
특정 메서드를 유틸성으로 제공하거나 static으로 선언된 변수를 제공하는 함수에는 static을 선언할 수 있다.
public class StaticUtil {
private static final int MAX_COUNT = 10;
public static int getApply(int count){
return MAX_COUNT * count;
}
}
영역(Block)
클래스 내의 특정 영역에 static으로 지정할 수 있다. 해당 영역은 클래스가 메모리에 올라갈 시점에 호출되는것을 알 수 있다.
호출 순서
- static
- 일반 block
- 생성자
public class StaticTest {
private int count = 0;
private static String name = "";
static{
name = "incheol";
System.out.println("static block!!!!");
}
{
name = "test";
System.out.println(count);
System.out.println("non static block!!!");
}
public StaticTest(int count) {
this.count = count;
name = "test22";
System.out.println("construct block");
}
public static void main(String[] args) {
System.out.println(StaticTest.name);
}
}
// 결과값
// static block!!!!
// non static block!!!
// construct block
// test22
static 메소드 적용 기준
- 유틸리티 클래스로 작성되고 불변으로 제공된다.
- 메소드내에서 인스턴스 변수를 사용하지 않는다.
- 인스턴스 생성에 의존하지 않는다.
- 메소드가 공유되고 있다면, 정적 메소드로 추출해낼 수 있다.
- 메소드가 변화되지 않고, 오버라이딩 되지 않는다.
static 데이터가 적재되는 Method Area란?
Method Area는 Class의 data(Method)와 Class의 Meta 정보(Field 이름, Field타입, Class 이름 등)를 저장한다. Java 8 이전에 Method Area를 PermGen(Permanat Generation Space)에 할당했다. Java 8 이후에는 PermGen이 완전히 제거 되어 Method Area는 Native Heap에 할당 된다.
static 제약 조건
static 영역 내에선 static 변수만 사용가능하다.
static 영역 내에서는 인스턴스 변수는 사용할 수 없다. 인스턴스 변수는 인스턴스 생성시 초기화 되므로 사용하는 시점과 초기화 시점이 다르므로 혼용해서 사용할 수 없기 때문이다. 그래서 실제로 compile 단계에서 에러를 확인할 수 있다.
static 영역 내에선 this 키워드를 사용할 수 없다.
상단의 제약 조건과 비슷한 조건으로 this 또한 사용할 수 없다.
참고
'Java' 카테고리의 다른 글
hashCode()와 equals() (0) | 2024.05.07 |
---|---|
Thread (0) | 2024.05.04 |
Enum (0) | 2024.04.29 |
JIT Compiler (0) | 2024.04.29 |
G1 GC vs ZGC (0) | 2024.04.29 |