자바 소스를 보다보면 자주 보이는 녀석. 오늘은 static 변수와 메서드에 대해서 글을 쓴다.
static?
static은 '정적인', '고정된'이라는 뜻을 가지고 있는 만큼, 클래스 안에서 static으로 선언된 변수나 메서드는 객체 없이 클래스 자체에 고정되어 공유되는 형태로 동작한다.
보통 우리가 어떤 클래스 안에 변수나 메서드를 다른 곳에서 사용하려면 객체 생성을 해줘야 한다.
예를 들어,
public class MathUtil {
public int square(int x) {
return x * x;
}
}
MathUtil util = new MathUtil();
int result = util.square(5);
이런 식으로 귀찮게 객체 생성을 한 번 해주고 메서드를 사용해야한다. 매번 이렇게 사용하면 귀찮고 코드도 많아질 것이다. 하지만 static을 사용한다면,
public class MathUtil {
public static int square(int x) {
return x * x;
}
}
int result = MathUtil.square(5);
간단하게 사용이 가능하다. 이걸 보고나면 우리가 보통 코딩을 처음 배우면 Main class에다가 main메서드를 만들어서 사용할 때 main 메서드에 static이 항상 붙는 이유를 알 수 있을 것이다.
static 사용시 주의할 점
static은 인스턴스 변수에 접근이 불가하다는 특징이 있다. 이게 무슨 말인지 간단한 코드를 보자.
public class Person {
String name;
public static void sayHello() {
System.out.println("Hello, " + name); // ⚠ 오류 발생!
}
}
위와 같이 코드를 짜면 오류가 난다. 왜 일어날까?
'name'은 인스턴스 변수이다. 즉, 'new Person()' 해서 만들어진 객체 안에 있는 값이다. 하지만 'sayHello()'는 static 메서드이므로 객체 없이도 호출이 가능하다. 그렇다면 객체 생성이 되지 않은 상태에서 인스턴스 변수를 쓰려고 하니 오류가 나는 것이다.
public class Person {
String name;
public void sayHello() {
System.out.println("Hello, " + name); // this.name 가능
}
}
여기서는 'sayHello()'가 static이 아니므로 객체가 있어야 호출되고, 그 객체의 'name'을 쓸 수 있다.
언제 static을 쓰면 좋을까?
- 객체의 상태에 의존하지 않는 기능 (ex. 덧셈, 날짜 계산 등)
Person p1 = new Person("영발");
p1.sayHello(); // 출력: Hello, 영발
Person마다 name이라는 상태(정보)를 갖는 경우, 해당 메서드는 p1이라는 객체가 어떤 이름을 갖고 있는지(상태)에 따라 결과가 바뀐다. 이런 경우에는 static을 사용하면 당연히 적절하지 못할 것이다.
public static int add(int a, int b) {
return a + b;
}
반대로 위와 같은 add 메서드는 누가 호출하든 결과가 같을 것이고 이와 같은 경우(입력만 있으면 결과가 항상 같은 계산, 변환 등)에 static을 사용하기 적절하다고 볼 수 있다.
- 유틸 클래스(Utils, Converter, Math)
유틸리티 클래스는 보통 여러 객체가 공통으로 사용할 수 있는 기능만 모아놓은 클래스다.
public class MathUtils {
public static int square(int x) {
return x * x;
}
public static int max(int a, int b) {
return a > b ? a : b;
}
}
예시 코드인 MathUtils를 보면 상태를 가지지 않고, 필드도 없다. 오직 기능만 있으므로 전부 static으로 만들어도 문제가 없다.
- 메인 함수('public static void main')처럼 프로그램 진입점
프로그램의 진입점은 클래스의 인스턴스 없이 실행되어야 하므로 static으로 선언되어야 한다.
-끝-
'공개 글' 카테고리의 다른 글
| Spring Batch(Tasklet)에서 트랜잭션 롤백(rollback)이 되지 않는 경우와 해결 방법 (1) | 2025.09.12 |
|---|---|
| Reflection과 Class 객체 (5) | 2025.07.31 |
| 트랜잭션(Transaction) (0) | 2025.04.28 |
| JavaScript 기본 (1) | 2025.03.24 |
| Web Server와 WAS (1) | 2025.03.17 |