기타 제어자(Non-access Modifier)의 종류
기본 구조 제어자 (설계 관련)
- static - 클래스 수준에서 공유되는 멤버를 정의하여 메모리에 한 번만 할당되고 모든 인스턴스가 공유하게 함
- final - 값 변경, 상속, 오버라이딩을 금지하여 불변성을 보장함
- abstract - 미완성 설계도를 제공하여 자식 클래스에서 반드시 구현하도록 강제함
특수 목적 제어자 (동작 관련)
- synchronized - 멀티스레드 환경에서 한 번에 하나의 스레드만 접근할 수 있도록 동기화를 보장함
- transient - 객체 직렬화 과정에서 특정 필드를 제외하여 보안성을 확보하거나 최적화함
- volatile - 멀티스레드 환경에서 변수의 값을 메인 메모리에서 직접 읽고 써서 항상 최신 값을 보장함
1. static
개념:
- 클래스 레벨에서 공유되는 멤버를 선언할 때 사용 (JS의 static과 유사)
- 객체 생성 없이 클래스 이름으로 직접 접근 가능
- 메모리에 한 번만 할당되어 모든 인스턴스가 공유
비유:
- 아파트의 공동현관 비밀번호와 같음 (모든 주민이 공유)
사용 목적:
- 메모리 효율성 향상
- 공통 자원 관리
- 유틸리티 메서드 구현
자주하는 실수:
- static 메서드에서 non-static 멤버 직접 접근
- 인스턴스 변수처럼 사용하려는 시도
실무 활용:
- 유틸리티 클래스 (Math, Arrays 등)
- 상수 정의
- 싱글톤 패턴 구현
2. final
개념:
- 변경 불가능한 요소 선언 (JS의 const와 유사)
- 클래스, 메서드, 변수에 사용 가능(각각 적용되는 기능이 다름)
- 클래스: 더 이상 확장(상속)할 수 없다
- 메서드: 더 이상 수정(오버라이딩)할 수 없다
- 변수: 더 이상 값을 변경할 수 없다
사용 목적:
- 불변성 보장
- 보안성 강화
- 상속/오버라이딩 방지
자주하는 실수:
- final 객체의 내부 상태 변경 가능성 간과
- 성능 최적화 목적으로만 사용
실무 활용:
- 상수 정의
- 불변 객체 생성
- API 설계시 확장 방지
3. abstract
개념:
- 추상 클래스/메서드 선언
- 구현부가 없는 메서드 정의 가능
- 클래스와 메서드 각각 적용되는 기능이 다르다
- 클래스: 추상 클래스 선언 (인스턴스화 불가)
- 메서드: 추상 메서드 선언 (구현부 없음)
사용 목적:
- 공통 기능 정의
- 확장성 보장
- 표준화된 설계 제공
자주하는 실수:
- 추상 클래스의 인스턴스화 시도
- 불필요한 추상화
실무 활용:
- 프레임워크 설계
- 템플릿 메서드 패턴
static vs non-static 비교:
특성 | static | non-static |
---|---|---|
메모리 할당 | 클래스 로딩 시 | 객체 생성 시 |
접근 방식 | 클래스명으로 직접 | 객체 생성 후 |
메모리 공유 | 모든 인스턴스 공유 | 인스턴스별 독립 |
사용 시기 | 공통 자원 관리 | 객체별 상태 관리 |
final vs non-final 비교:
특성 | final | non-final |
---|---|---|
값 변경 | 불가능 | 가능 |
상속 | 불가능 | 가능 |
오버라이딩 | 불가능 | 가능 |
메모리 | 최적화 가능 | 일반적 |
실무 활용 예시:
// 유틸리티 클래스
public final class StringUtils {
private static final int MAX_LENGTH = 100;
public static String trim(String str) {
return str != null ? str.trim() : "";
}
}
// 추상 클래스
public abstract class BaseService {
protected abstract void process();
public final void execute() {
// 템플릿 메서드 패턴
preProcess();
process();
postProcess();
}
}
아니요, 추가적인 기타 제어자들이 있습니다:
4. synchronized
개념:
- 멀티스레드 환경에서 동기화를 보장하는 제어자
- 한 번에 하나의 스레드만 접근 가능하도록 제어
- 메서드와 블록 레벨에서 적용되는 기능이 다르다
- 메서드: 메서드 전체가 동기화 구역
- 블록: 특정 블록만 동기화 구역
비유:
- 화장실 사용시 잠금장치와 같음 (한 명이 사용 중일 때 다른 사람 접근 불가)
사용 목적:
- 스레드 안전성 확보
- 데이터 일관성 유지
- 경쟁 상태(Race Condition) 방지
자주하는 실수:
- 과도한 동기화로 인한 성능 저하
- 데드락 발생 가능성
- 동기화 범위를 너무 크게 설정
실무 활용:
- 공유 자원 접근 제어
- 멀티스레드 환경의 데이터 처리
- 싱글톤 패턴의 스레드 안전성 보장
5. transient (변수에만 적용)
개념:
- 직렬화 과정에서 제외할 필드 지정
- 민감한 데이터나 불필요한 데이터 제외
사용 목적:
- 보안 데이터 보호
- 직렬화 용량 최적화
- 불필요한 데이터 제외
자주하는 실수:
- 역직렬화 시 null 처리 미흡
- 필요한 필드를 실수로 제외
실무 활용:
- 패스워드 등 보안 정보 처리
- 캐시된 데이터 필드 제외
- 임시 계산 결과 필드 제외
6. volatile (변수에만 적용)
개념:
- 변수의 값을 메인 메모리에서 직접 읽고 쓰도록 보장
- 캐시된 값이 아닌 실제 값 사용 보장
사용 목적:
- 멀티스레드 환경에서 변수의 가시성 보장
- 메모리 일관성 확보
자주하는 실수:
- synchronized와의 차이점 혼동
- 복합 연산에서의 원자성 미보장 오해
실무 활용:
- 상태 플래그 변수
- 멀티스레드 환경의 공유 변수
동기화 관련 제어자 비교:
특성 | synchronized | volatile |
---|---|---|
범위 | 블록/메서드 | 변수 |
기능 | 상호배제+가시성 | 가시성 |
복합연산 원자성 | 보장 | 미보장 |
성능영향 | 있음 | 적음 |
실무 활용 예시:
public class ThreadSafeCounter {
private volatile boolean running = true;
private int count = 0;
public synchronized void increment() {
count++;
}
public void stop() {
running = false;
}
}
class UserInfo implements Serializable {
private String username;
private transient String password; // 직렬화 제외
private transient Cache cache; // 임시 데이터 제외
}
이러한 제어자들은 주로 다음과 같은 상황에서 사용:
- 멀티스레드 프로그래밍
- 분산 시스템
- 보안이 중요한 애플리케이션
- 고성능이 요구되는 시스템
각 제어자의 핵심 차이점
1. static
- 클래스 레벨 공유
- 메모리에 한번만 할당
- 객체 생성 없이 사용
public class Example { static int count = 0; // 모든 인스턴스가 공유 int normalCount = 0; // 각 인스턴스마다 별도 존재 }
2. final
- 값 변경 방지
- 상속/오버라이드 방지
final class NoInheritance {} // 상속 불가 class Parent { final void noOverride() {} // 오버라이드 불가 final int CONSTANT = 100; // 값 변경 불가 }
3. abstract
- 미완성 설계도
- 구현 강제
abstract class Animal { abstract void makeSound(); // 반드시 자식클래스에서 구현해야 함 }
4. synchronized
- 스레드 동기화
- 한 번에 하나의 스레드만 접근
public class Counter { synchronized void increment() { // 한 번에 하나의 스레드만 실행 가능 // 코드 } }
5. transient
- 직렬화 제외
class User implements Serializable { String name; transient String password; // 직렬화 시 제외됨 }
6. volatile
- 메인 메모리 직접 접근
- 캐시 무시
public class Flag { volatile boolean stop = false; // 항상 최신 값 보장 }
핵심 차이점 표:
제어자 | 주요 목적 | 적용 대상 | 특징 |
---|---|---|---|
static | 공유 | 클래스,멤버 | 메모리 한번 할당 |
final | 불변 | 클래스,멤버,변수 | 수정 불가 |
abstract | 구현 강제 | 클래스,메서드 | 구현부 없음 |
synchronized | 동기화 | 메서드,블록 | 스레드 안전 |
transient | 직렬화 제외 | 필드 | 보안/최적화 |
volatile | 가시성 보장 | 변수 | 캐시 미사용 |
실제 사용 예시:
public abstract class BaseService {
private static final int MAX_RETRY = 3; // static + final
private volatile boolean running; // volatile
private transient Cache cache; // transient
public synchronized void process() { // synchronized
// 처리 로직
}
protected abstract void doProcess(); // abstract
}
'Java > 자바 개념' 카테고리의 다른 글
인터페이스에 정의할 수 있는 요소들 (0) | 2025.05.02 |
---|---|
❓ 자바스크립트의 세미콜론(;) 사용: } 뒤의 경우 (0) | 2025.03.31 |