싱글톤 디자인 패턴
싱글톤 패턴은 객체를 한 번만 생성하여 메모리 사용을 줄이고 일관성을 유지하는 데 유용합니다.
- 즉시 초기화 방식(Eager Initialization): 클래스 로딩 시점에 인스턴스를 생성하므로 스레드 안전하지만 메모리 점유 시간이 길 수 있습니다.
- 지연 초기화 방식(Lazy Initialization): 필요할 때 인스턴스를 생성하므로 메모리를 절약하지만 멀티스레드 환경에서는 동기화 문제가 발생할 수 있습니다.
즉시 초기화 구현
public class SingletonEager {
private static final SingletonEager INSTANCE = new SingletonEager();
private SingletonEager() {}
public static SingletonEager getInstance() {
return INSTANCE;
}
}
지연 초기화 구현
public class SingletonLazy {
private static SingletonLazy instance;
private SingletonLazy() {}
public static SingletonLazy getInstance() {
if (instance == null) {
instance = new SingletonLazy();
}
return instance;
}
}
열거형(Enum)
열거형은 고정된 개수의 상수 값을 정의하고 이를 관리하기 위한 특별한 데이터 타입입니다.
사용자 정의 열거형 클래스
public class SeasonDemo {
public static void main(String[] args) {
Season spring = Season.SPRING;
System.out.println(spring.getDescription());
}
}
class Season {
public static final Season SPRING = new Season("봄", "따뜻함");
public static final Season SUMMER = new Season("여름", "더위");
public static final Season FALL = new Season("가을", "선선함");
public static final Season WINTER = new Season("겨울", "추위");
private final String name;
private final String description;
private Season(String name, String desc) {
this.name = name;
this.description = desc;
}
public String getName() { return name; }
public String getDescription() { return description; }
}
enum 키워드 사용
enum SeasonType {
SPRING("봄", "따뜻함"),
SUMMER("여름", "더위"),
FALL("가을", "선선함"),
WINTER("겨울", "추위");
private final String name;
private final String desc;
SeasonType(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() { return name; }
public String getDesc() { return desc; }
}
enum의 주요 메서드
public class EnumExample {
public static void main(String[] args) {
SeasonType season = SeasonType.FALL;
System.out.println(season.ordinal()); // 인덱스 출력
System.out.println(season.name()); // 이름 출력
for (SeasonType s : SeasonType.values()) {
System.out.println(s);
}
}
}
인터페이스 구현
interface Displayable {
void display();
}
enum Weather implements Displayable {
SUNNY {
public void display() {
System.out.println("맑음");
}
},
RAINY {
public void display() {
System.out.println("비옴");
}
};
public abstract void display();
}
예외 처리(Exception Handling)
자바에서는 Throwable 클래스를 기반으로 모든 예외와 오류를 처리합니다.
- Error: JVM 수준의 치명적인 문제로 개발자가 직접 처리하지 않음
- Exception: 프로그램에서 처리 가능한 예외로 Checked/Unchecked로 구분됨
예외 처리 방법
try-catch-finally 구문
public class ExceptionHandling {
public static void readFile(String path) {
FileInputStream fis = null;
try {
fis = new FileInputStream(path);
int data;
while ((data = fis.read()) != -1) {
System.out.print((char)data);
}
} catch (FileNotFoundException e) {
System.err.println("파일을 찾을 수 없습니다.");
} catch (IOException e) {
System.err.println("입출력 오류 발생");
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
System.err.println("리소스 해제 실패");
}
}
}
}
}
throws 선언
public class ThrowsExample {
public void processData() throws IOException, SQLException {
// 파일 읽기 또는 DB 작업 수행
}
}
사용자 정의 예외
class InvalidAgeException extends RuntimeException {
public InvalidAgeException(String msg) {
super(msg);
}
}
public class AgeValidator {
public static void validate(int age) {
if (age < 0 || age > 150) {
throw new InvalidAgeException("유효하지 않은 나이 값입니다.");
}
}
}
어노테이션(Annotation)
어노테이션은 코드에 메타데이터를 추가하여 컴파일러나 런타임에 특정 동작을 지시하는 데 사용됩니다.
표준 어노테이션
- @Override: 메서드 재정의 검증
- @Deprecated: 더 이상 사용되지 않는 요소 표시
- @SuppressWarnings: 경고 억제
커스텀 어노테이션
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Timer {
int delay() default 1000;
String unit() default "milliseconds";
}
메타 어노테이션
- @Retention: 어노테이션 유지 정책 설정
- @Target: 적용 대상 지정
- @Documented: 문서 포함 여부
- @Inherited: 상속 가능 여부