1. 개요
Java에서 클래스, 인터페이스, 변수, 메서드 등 요소에 적용 가능한 수정자(Modifiers)는 해당 요소의 **접근 범위**, **행동 특성**, **생애 주기**를 정의합니다. 주요 분류는 다음과 같습니다:- 접근 제어 수정자: 시스템 내부/외부에서의 가시성 조절
- 비접근 제어 수정자: 행동 특성 설정 (static, final, abstract 등)
2. 접근 제어 수정자
Java는 4가지 접근 수준을 제공합니다 (가장 엄격한 순서): private < default < protected < public| 수정자 | 같은 클래스 | 같은 패키지 | 하위 클래스 | 다른 패키지 |
|---|---|---|---|---|
| private | ○ | × | × | × |
| default | ○ | ○ | × | × |
| protected | ○ | ○ | ○ | × |
| public | ○ | ○ | ○ | ○ |
참고: - default: 명시하지 않은 경우 - 하위 클래스: 현재 클래스를 상속받은 모든 클래스 - 다른 패키지: 같은 패키지도 아닐 뿐만 아니라 상속 관계도 없는 클래스
2.1 사용 사례 예시
public class User {
private String username; // 외부 접근 불가
public void setUsername(String username) {
this.username = username; // 공개 메서드를 통해 접근
}
}
// 패키지: com.example.util
class Helper { // default 수정자
void process() { ... }
}
// 동일 패키지 내 클래스만 접근 가능
public class Parent {
protected void display() { ... }
}
public class Child extends Parent {
public void test() {
display(); // 하위 클래스 접근 가능
}
}
public class EntryPoint {
public static void main(String[] args) { ... }
}
3. 비접근 제어 수정자
요소의 행동 특성을 정의하는 수정자들입니다.
3.1 static
클래스 수준으로 선언되며, 객체 생성 없이도 접근 가능합니다.
public class DataContainer {
private static int itemCount = 0;
private String itemName;
public DataContainer(String itemName) {
this.itemName = itemName;
itemCount++; // 모든 인스턴스 공유
}
public static int getItemCount() {
return itemCount;
// return itemName; // 오류: 비정적 변수 접근 불가
}
}
3.2 final
변경 불가능한 상태로 설정합니다.
public final class Utility {
public static final double GRAVITY = 9.81;
public final void calculate() {
System.out.println("Final method");
}
}
3.3 abstract
구현되지 않은 추상 메서드를 포함할 수 있는 클래스입니다.
public abstract class Shape {
public abstract void draw();
public void rotate() {
System.out.println("Rotation");
}
}
public class Circle extends Shape {
@Override
public void draw() {
System.out.println("Drawing circle");
}
}
3.4 synchronized
멀티스레드 환경에서 동기화 처리
public class Counter {
private int value = 0;
public synchronized void increment() {
value++;
}
}
3.5 volatile
메모리可见성 보장 및 인스트럭션 리오더 방지
public class TaskMonitor {
private volatile boolean isRunning = true;
public void stopTask() {
isRunning = false; // 변경 시 즉시 다른 스레드에 반영
}
}
3.6 transient
직렬화 시 무시되는 필드
public class AuthData implements Serializable {
private String userId;
private transient String token; // 직렬화 시 생략
}
3.7 native
C/C++ 등 다른 언어로 구현된 메서드
public class NativeWrapper {
public static native void performOperation();
}
3.8 strictfp
IEEE 754 기준으로 연산 수행
public strictfp class PrecisionCalc {
public double compute(double a, double b) {
return a + b;
}
}
4. 수정자 조합 규칙
특정 조합은 컴파일 오류 발생
| 불가 조합 | 원인 |
|---|---|
| abstract + final | 추상 클래스는 상속 필요 |
| abstract + private | 추상 메서드 재정의 필요 |
| static + abstract | 정적 메서드 재정의 불가능 |
| private + protected/public | 접근 제어자 충돌 |
| synchronized + native | native 메서드는 저수준 제어 |
| 가능 조합 | 예시 | 설명 |
|---|---|---|
| public static | main 메서드 | 공개 정적 메서드 |
| private final | 변수 초기화 | 사용자 ID 상수 |
| protected abstract | 추상 메서드 | 하위 클래스 재정의 요구 |
| public abstract | 추상 클래스 | 구현 강제 |
| static final | 상수 정의 | 정적 상수 |
| synchronized | 동기화 메서드 | 스레드 안전 처리 |
5. 표준 작성 순서
코드 가독성을 위해 권장 순서:
- 접근 제어자 (public, protected, private)
- 비접근 제어자 (static, abstract, final 등)
- strictfp
// 권장 순서
public static final int MAX_LIMIT = 100;
private synchronized void processData() { ... }
protected abstract void render();
6. 흔한 실수 사항
Q1: static이 지역 변수에 적용 가능?
A: 불가능. 멤버 변수, 메서드, 코드 블록, 내부 클래스에만 적용 가능
Q2: final 참조 변수의 객체 내용 변경 가능?
A: 가능. 참조 주소는 변경 불가능하지만, 객체 내부 상태는 수정 가능
final List<String> items = new ArrayList<>();
items.add("Item"); // ✅ 가능
// items = new ArrayList<>(); // ❌ 불가능
Q3: 추상 클래스는 생성자 사용 가능?
A: 가능. 자식 클래스에서 호출되어 부모 클래스 멤버 초기화
Q4: 인터페이스의 변수 기본 수정자?
A: public static final
Q5: 인터페이스 메서드 기본 수정자?
A: Java 8 이전: public abstract
Java 8 이후: default나 static 메서드 지원
7. 요약표
| 수정자 | 핵심 기능 | 적용 사례 |
|---|---|---|
| private | 내부 접근 | 데이터 은닉 |
| default | 패키지 내 접근 | 보조 유틸리티 |
| protected | 하위 클래스 접근 | 확장 가능 클래스 |
| public | 전체 접근 | API 메서드 |
| static | 클래스 수준 | 상수, 툴 메서드 |
| final | 불변성 | 상수, 확장 금지 |
| abstract | 추상화 | 인터페이스 설계 |
| synchronized | 동기화 | 공유 자원 처리 |
| volatile | 메모리可见성 | 스레드 간 통신 |
| transient | 직렬화 무시 | 민감 정보 |