static이란?
static(정적)은 고정된이라는 의미를 가지고 있다.
static이라는 키워드를 사용하여 static 변수와 static 메서드를 만들 수 있는데 이를 정적 필드와 정적 메서드라고도 하며, 둘을 합쳐 정적 멤버(클래스 멤버)라고 한다.
이렇게 만들어진 정적 변수나 정적 메서드는 프로그램이 종료되기 전까지 사용이 가능하고, GC(Garbage Collection)에 의해 수집되지 않는다. 참고로, 정적 객체는 GC에 의해 수집될 수 있다.
이 정적 필드와 정적 메서드는 객체(인스턴스)에 소속된 멤버가 아니라 클래스에 고정된 멤버이다.
∴ 클래스 로더가 클래스를 로딩해서 메서드 메모리 영역에 적재할 때 클래스 별로 관리가 된다.
→ 클래스의 로딩이 끝나는 즉시 바로 사용이 가능
* 가비지 컬렉션(Garbage Collection)
: 줄여서 GC라고도 부르며, 가비지 컬렉션은 자바의 메모리 관리 방법 중의 하나로 JVM의 Heap 영역에서 동적으로 할당했던 메모리 영역 중 필요 없게 된 메모리 영역을 주기적으로 삭제하는 프로세스를 말한다.
C나 C++에서는 이러한 가비지 컬렉션이 없어 프로그래머가 수동으로 메모리 할당과 해제를 일일이 해줘야 하는 반면 Java는 JVM에 탑재되어 있는 가비지 컬렉터가 메모리 관리를 대행해주기 때문에 개발자 입장에서 메모리 관리, 메모리 누수 문제에 대해 신경을 덜 쓰고 개발에만 집중할 수 있다는 장점이 있다.

static을 지양해야 하는 이유
· 메모리 문제
static은 프로그램 실행 시점에 메모리에 할당하며, 웬만하면 프로그램 종료 시점까지 메모리에서 해제되지 않는다.
· 동시성 이슈 문제
static은 전역에서 접근이 가능하므로 별도의 동기화 전략을 수립해야 한다.
· 런타임 다형성 불가
static으로만 이루어진 메서드를 사용하는 객체의 경우, 해당 객체를 메모리로 할당하여 사용하는 것이 아니고 객체 메서드로 바로 접근하여 호출한다.
· 객체의 상태를 이용X
정적 메서드 안에는 클래스의 인스턴스 필드를 사용할 수 없기 때문에 정적 메서드를 사용하기 위해 필요로 하는 인자는 모두 외부에서 주입해야 한다.
· 테스트의 어려움
정적 필드는 전역으로 관리되기 때문에 프로그램 전체에서 이 필드에 접근하고 수정할 수 있다. 따라서 해당 필드를 추론하기 어려워 테스트가 까다롭다.
그럼 static은 언제 ?
· 상수 정의
절대 변하지 않는 변수를 상수라고 하는데, 해당 상수는 객체 내에서 매번 일반 변수로 정의하기 보다는 한 번 정적 변수로 정의하면 메모리를 아낄 수 있다.
→ 전역적으로 쉽게 재사용하는 멤버나 잘 변하지 않는 변수나, 메서드를 사용할 때 static을 쓴다.
· 유틸리티 클래스 정의
유틸리티 클래스는 인스턴스 메서드와 인스턴스 변수를 제공하지 않고, 데이터 처리를 위한 정적 메서드만 존재하는 클래스를 말한다. java에서 Math 클래스를 보면, 상수 외에 인스턴스 변수가 하나도 없고 계산을 위한 정적 메서드만 제공한다.
이처럼 애초부터 객체의 상태를 이용할 생각이 없고, 여러 객체들의 필요에 의해 데이터를 처리하는 공통 로직이 필요할 때는 static을 사용하여 설계하면 좋다.
static 메서드 사용 예시
class Student{
static void pr_name() { // 클래스 메서드
System.out.println("이름 출력");
}
void pr_num() { // 인스턴스 메서드
System.out.println("학번 출력");
}
}
public class Main{
public static void main(String[] args) {
Student.pr_name(); // 인스턴스를 생성하지 않아도 호출 가능
Student student = new Student();
student.pr_num(); // 인스턴스를 생성해야 호출 가능
}
}