[Java] Generics, Enum, Annotation
by Frinee1. 제네릭스(Generics)
1.1. 제네릭스란?
- 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입을 체크해 주는 기능
- 객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형변환의 번거로움을 줄여줌.
- 제네릭스의 장점
- 타입의 안정성을 제공함.
- 타입체크의 형변환을 생략할 수 있으므로 코드가 간결해짐.
1.2. 제네릭 클래스의 선언
// 여기서 T는 임의의 참조형 타입이다.
// T에 원하는 타입을 지정하여 사용할 수 있다.
class Box<T> {
T item;
void setItem(T item) { this.item = item; }
T getItem() { return item;}
}
Box<String> b = new Box<String>(); // 타입 T 대신 실제 타입 지정
b.setItem(new Object()); // 에러, 지정한 String 외에는 지정불가
b.setItem("ABC"); // OK
String item = (String)b.getItem(); // 형변환이 필요없음
- 주의사항
- 제네릭 타입을 지정하지 않아도 객체 생성이 허용되지만 안전하지 않다는 경고가 발생
- 타입 변수 T에 Object타입을 지정하면, 경고가 발생하지 않음

- 제네릭스 용어
- Box<T> : 제네릭 클래스, ‘T의 Box’ 또는 ‘T Box’라고 읽는다.
- T : 타입 변수 또는 타입 매개변수. (T는 타입 문자)
- Box : 원시 타입(raw type)
- 제네릭스 제한
- T는 인스턴스변수로 간주되기 때문에 모든 객체에 대해 동일하게 동작해야 하는 static멤버에 타입 변수 T를 사용할 수 없음
- 제네릭 타입의 배열 선언은 가능하나 배열을 생성하는 것은 허용되지 않음
- new 연산자는 컴파일 시점에 타입을 정확하게 알고 있어야 함.
1.3. 제네릭 클래스의 객체 생성과 사용
- 참조변수와 생성자에 대입된 타입이 일치해야 함.
- 두 타입이 상속관계에 있는 경우에도 대입된 타입은 일치해야 함.
- JDK1.7부터는 추정이 가능한 경우 타입을 생략할 수 있게 됨.
Box<Apple> appleBox = new Box<>(); // JDK1.7부터 가능
Box<Apple> appleBox = new Box<Apple>(); // OK
Box<Apple> appleBox = new Box<Grape>(); // 에러
Box<Fruit> appleBox = new Box<Apple>(); // 에러
1.4. 제한된 제네릭 클래스
- 타입 매개변수 T에 지정할 수 있는 타입의 종류를 제한하는 방법이 존재함.
- 제네릭에 extends 를 사용하면 특정 타입의 자손들만 대입할 수 있게 제한할 수 있음.
- 인터페이스를 구현하는 제약을 사용할 때에도 extends 를 사용한다.
class FruitBox<T extends Fruit> { // Fruit의 자손 타입만 지정가능
ArrayList<T> list = new ArrayList<T>();
...
}
1.5. 와일드 카드
// 매개변수에 과일박스를 대입하면 주스를 만들어 반환하는 클래스
class Juicer {
static Juice makeJuice(FruitBox<Fruit> box) {
String tmp = "";
for(Fruit f : box.getList()) tmp += f + " ";
return new Juice(tmp);
}
}
- 이 경우, 제네릭 타입을 FruitBox<Fruit> 로 고정해버리면 Apple 과 같은 다른 과일의 타입을 활용할 수 없는 문제가 발생
- 이럴 때 사용하기 위해 고안된 것이 와일드 카드이며 와일드 카드 기호는 “?” 로 표현
- extends 와 super 로 제한할 수 있음.
- <? extends T> : 와일드 카드의 상한 제한. T와 그 자손들만 가능
- <? super T> : 와일드 카드의 하한 제한. T와 그 조상들만 가능
- <?> : 제한 없음. 모든 타입이 가능
1.6. 제네릭 메서드
- 메서드의 선언부에 제네릭 타입이 선언된 메서드를 제네릭 메서드라 한다.
- 제네릭 메서드는 제네릭 클래스가 아닌 클래스에서도 정의가 가능하다.
// Collections.sort()
static <T> void sort(List<T> List, Comparator<? super T> c)
class FruitBox<T> {
...
static <T> void sort(List<T> list, Comparator<? super T> c){
...
}
}
2. 열거형(Enum)
2.1. 열거형(Enum)이란?
- 서로 관련된 상수를 편리하게 선언하기 위한 기능
- 자바의 열거형은 값뿐만 아니라 타입도 관리하기 때문에 논리적 오류를 줄일 수 있음
class Card {
enum Kind { CLOVER, HEART, DIAMOND, SPADE }
enum Value { TWO, THREE, FOUR }
final Kind kind;
final Value value;
}
2.2. 열거형의 정의와 사용
enum 열거형이름 { 상수명1, 상수명2, ... }
enum Direction { EAST, SOUTH, WEST, NORTH }
class Unit {
int x, y;
Direction dir;
void init() {
dir = Driection.EAST;
}
}
- 열거형 상수간의 비교는 == 를 사용할 수 있음.
- 열거형의 메서드
| 메서드 | 설명 |
| Class<E> getDeclaringClass() | 열거형의 Class객체를 반환 |
| String name() | 열거형 상수의 이름을 문자열로 반환 |
| int ordinal() | 열거형 상수가 정의된 순서를 반환 (0부터 시작) |
| T valueOf(Class<T> enumType, String name) | 지정된 열거형에서 name과 일치하는 열거형 상수를 반환 |
| static E values() | 열거형에 정의된 모든 상수를 출력 |
- 열거형의 값 지정하기
enum Direction {
EAST(1), SOUTH(5), WEST(-1), NORTH(10);
private final int value;
Direction(int value) { this.value = value; }
public int getValue() { return value; }
}
3. 애너테이션(Annotation)
3.1. 애너테이션(Annotation)이란?
- 소스코드와 문서를 하나의 파일로 관리하는 것이 낫다고 생각하고 개발을 했다고 한다..
- 소스코드의 주석 /** ~ */ 에 소스코드에 대한 정보를 저장하고, 소스코드 주석으로부터 HTML문서를 생성하는 프로그램(javadoc.exe)을 만들어 사용함.
- 이 기능을 응용해서 프로그램의 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함시킨 것이 애너테이션이다.
- 애너테이션은 주석처럼 프로그래밍 언어에 영향을 미치지 않으면서도 다른 프로그램에게 유용한 정보를 줄 수 있음
3.2. 표준 애너테이션
| 애너테이션 | 설명 |
| @Override | 컴파일러에게 오버라이딩하는 메서드라는 것을 알린다. |
| @Deprecated | 앞으로 사용하지 않을 것을 권장하는 대상에게 붙인다. |
| @SuppressWarnings | 컴파일러의 특정 경고메시지가 나타나지 않게 해준다. |
| @SafeVarargs | 지네릭스 타입의 가변인자에 사용한다. (JDK1.7) |
| @FunctionalInterface | 함수형 인터페이스라는 것을 알린다.(JDK1.8) |
| @Native | native메서드에서 참조되는 상수 앞에 붙인다. (JDK1.8) |
메타 애너테이션
- 애너테이션을 위한 애너테이션, 즉 애너테이션에 붙이는 애너테이션
- 애너테이션을 정의할 때 애너테이션의 적용대상이나 유지기간 등을 지정하는데 사용
| 애너테이션 | 설명 |
| @Target | 애너테이션이 적용가능한 대상을 지정하는데 사용 |
| @Documented | 애너테이션 정보가 javadoc으로 작성된 문서에 포함되게 한다. |
| @Inherited | 애너테이션이 자손 클래스에 상속되도록 한다. |
| @Retention | 애너테이션이 유지되는 범위를 지정하는데 사용 |
| @Repeatable | 애너테이션을 반복해서 적용할 수 있게 한다.(JDK1.8) |
애너테이션 요소 규칙
- 요소의 타입은 기본형, String, Enum, Annotation, Class만 허용
- ( )안에 매개변수를 선언할 수 없다.
- 예외를 선언할 수 없음
- 요소를 타입 매개변수로 정의할 수 없음.
'Backend > Java' 카테고리의 다른 글
| [Java] 중첩 클래스(Nested class) (5) | 2025.07.25 |
|---|---|
| [Java] 예외 처리(exception handling) (0) | 2025.02.11 |
| [Java] 컬렉션 프레임워크(Collections Framework) (1) | 2025.02.09 |
| [Java] 객체지향 프로그래밍 (OOP) (0) | 2025.01.27 |
| 자바 기본 구조와 기본 문법 (0) | 2025.01.18 |
블로그의 정보
프리니의 코드저장소
Frinee