Ch.12 지네릭스, 열거형, 애너테이션
- 지네릭스(Generics)
- 지네릭스란
- 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입 체크를 위해 사용
- 장점
- 타입의 안정성을 높임
- 타입 체크와 형변환을 생략할 수 있으므로 코드가 간결
- 지네릭 클래스의 선언
- 지네릭 클래스로 변환하는 방법
- 클래스이름 옆에 <T> 붙임
- Object를 모두 T로 변환
- T: 타입 변수(Type variable)
- E: element
- 기호의 종류만 다를 뿐 임의의 참조형 타입을 의미함
- 지네릭스 용어
- 원시 타입, 지네릭 클래스, 타입 매개변수 또는 타입 변수
- 지네릭스의 제한
- 모든 객체에 동일하게 작동해야 하는 static멤버에 타입 변수 T를 사용할 수 없음
- 지네릭 배열로 선언할 수 없음
- 컴파일하는 시점에서 T가 어떤 타입이 될 지 모르기 때문
- 지네릭 클래스로 변환하는 방법
- 지네릭 클래스의 객체 생성과 사용
- 참조변수와 생성자에 대입한 타입(매개변수화된 타입)이 일치해야 함
- 지네릭 타입은 상속 관계여도 사용할 수 없음
- 지네릭 클래스가 상속 관계일 때, 대입한 타입이 같으면 사용 가능함
- 제한된 지네릭 클래스
- 목적: 한 종류 뿐만 아니라 다양한 종류의 타입을 받기 위해서 사용
- 제네릭 타입에 extends를 사용: 특정 타입 + 그 타입의 자손들만 대입할 수 있게 제한됨
- 인터페이스도 구현해야한다면 &로 연결
- 와일드 카드
- 지네릭 타입이 다른 것만으로는 오버로딩 조건이 성립되지 않음
- 와일드 카드 - ?
- Object와 다를 것이 없음
- 어떤 타입도 들어올 수 있음
- 상한(upper bound)와 하한(lower bound)
- 상한 제한
- <? extends T>
- T와 그 자손들만 가능
- 하한 제한
- <? super T>
- T와 그 조상들만 가능
- 상한 제한
- <?> == <? extends Object>
- 지네릭 메서드
- 의미: 메서드의 선언부에 지네릭 타입이 선언된 메서드
- 지네릭 클래스에 정의된 타입 매개변수 != 지네릭 메서드에 정의된 타입 매개변수
- static 메서드에는 지네릭 사용 가능
- 지네릭 타입의 형변환
- 지네릭 타입과 넌지네릭 타입의 형변환 가능
- 대입된 타입이 다른 지네릭 타입간에는 형변환 불가능
- 지네릭 타입의 제거
- 컴파일러는 지네릭 타입을 이용해서 소스파일을 체크하고, 필요한 곳에 형변환을 넣어 준 후 지네릭 타입을 제거
- 컴파일된 파일(*.class)에는 지네릭 타입에 대한 정보가 없음
- 이전의 소스 코드와의 호환성을 위해
- 열거형(enums)
- 열거형이란
- 타입의 안전한 열거형(typesafe enum)
- C언어의 열겨형보다 향상된 기능을 가짐: 열거형이 갖는 값뿐만 아니라 타입까지 관리해서 논리적인 오류를 줄일 수 있음
- 실제 값이 같아도 타입이 다르면 false
- 사용 이유: 상수의 값이 바뀌면 해당 상수를 참조하는 모든 소스를 다시 컴파일해야하지만, 열거형 상수를 이용하면 기존의 소스를 다시 컴파일하지 않아도 됨
- 타입의 안전한 열거형(typesafe enum)
- 열거형의 정의와 사용
- 형식: enum 열거형이름 { 상수명1, 상수명2, ... }
- 사용 방법: 열거형이름.상수명
- 열거형 상수간의 비교에는 '=='이 사용 가능 → 빠른 성능 제공
- 단 비교 연산자 '>', '<'는 사용할 수 없음 → compareTo() 사용
- java.lang.Enum 클래스: 모든 열거형의 조상
- values() 메서드: 통해 열거형의 모든 상수를 배열에 담아 반환
- valueOf() 메서드: 열거형 상수의 이름으로 상수에 대한 참조를 얻을 수 있음
- 열거형에 멤버 추가하기
- Enum 클래스의 ordinal()이 상수가 정의된 순서를 알려주지만 사용하지 않는 것이 좋음
- 열거형 상수 값이 불규칙한 경우 → 상수의 이름 옆에 원하는 값을 괄호()와 함께 적어주면 됨
- 지정된 값을 저장할 수 있는 인스턴스 변수와 생성자 필요
- 열거형의 생성자는 묵시적으로 private
- 상수에 여러 값을 지정 가능 → 그에 맞게 변수와 생성자 추가
- 열거형에 추상 메서드 추가하기
- 추상 메서드를 선언하면 각 열거형 함수가 이 추상 메서드를 구현해야함
- 열거형의 이해
- 열거형 상수 각각 열거형의 객체
- 열거형 상수의 값은 객체의 주소이고, 이 값이 바뀌지 않는 값이므로 '=='으로 비교가 가능한 것
- 그래서 추상 메서드를 추가하면, 각 객체마다 구현해줘야하는 것
- 애너테이션(annotation)
- 애너테이션이란
- 의미: 프로그램의 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함 시킨 것
- JDK에서 제공하는 표준 애너테이션은 주로 컴파일러를 위해 정보를 제공하는 역할
- 메타 애너테이션: 새로운 애너테이션을 정의할 때 사용
- 표준 애너테이션
- 애너테이션 종류 (메타 애너테이션 제외)
- @Override: 컴파일러에게 오버라이딩이라는 것을 알림
- @Deprecated: 앞으로 사용하지 않을 것을 권고
- @SupperessWaring: 컴파일러의 특정 경고 메세지가 나타나지 않게 설정
- @SafeVarags: 지네릭스 타입의 가변인자에 사용
- @FuntionalInterface: 함수형 인터페이스라는 것을 알림
- @Native: native 메서드에서 참조되는 상수 앞에 붙임
- 애너테이션 종류 (메타 애너테이션 제외)
- 메타 애너테이션
- 애너테이션을 위한 애너테이션
- 애너테이션에 붙이는 애너테이션
- 애너테이션을 정의할 때 사용
- 종류
- @Target: 애너테이션에 적용 가능한 대상을 지정하는데 사용
- @Document: 애너테이션 정보가 java.doc으로 작성된 문서에 포함되도록 함
- @Inherited: 애너테이션이 자손 클래스에 상속되도록 함
- @Retention: 애너테이션이 유지되는 범위를 지정하는데 사용
- @Repeatable: 애너테이션을 반복해서 적용할 수 있게함
- 애너테이션을 위한 애너테이션
- 애너테이션의 타입 정의하기
- 인터페이스 정의법 + '@' 기호를 붙이기
- 애너테이션의 요소: 애너테이션 내에 선언된 메서드
- 반환값 존재 + 매개변수는 없는 추상 메서드의 형태
- 상속을 통해 구현하지 않아도 됨
- 단, 애너테이션을 적용할 때 값을 입력해줘야함
- 각 요소들은 기본값을 가질 수 있으며, 기본값을 가진 요소는 입력 값이 없을 때 사용
- 요소가 하나인 경우: 요소의 이름 생략 가능
- 요소의 타입이 배열인 경우: 괄호{}를 사용해서 여러 개의 값을 지정
- java.lang.annotation.Annotation: 모든 애너테이션의 조상
- 애너테이션은 상속을 허용하지 않으므로 조상으로 지정할 수 없음
- 마커 애너테이션
- 값을 지정할 필요가 없는 경우, 애너테이션의 요소를 하나도 지정하지 않을 수 있음
- 요소가 하나도 정의되어 있지 않은 애너테이션을 의미
- 애너테이션 요소의 규칙
- 요소의 타입은 기본형, String, enum, 애너테이션, Class만 허용
- ()안에 매개변수를 선언할 수 없음
- 예외를 선언할 수 없음
- 요소를 타입 매개변수로 정의할 수 없음
'JAVA 기초' 카테고리의 다른 글
[JAVA 기초] JAVA의 정석 - Ch.14 람다와 스트림 (정리) (1) | 2025.01.24 |
---|---|
[JAVA 기초] JAVA의 정석 - Ch.13 쓰레드(Thread) (정리) (2) | 2025.01.23 |
[JAVA 기초] JAVA의 정석 - Ch.11 컬렉션 프레임웍 (정리) (1) | 2025.01.21 |
[JAVA 기초] JAVA의 정석 - Ch.10 날짜와 시간 & 형식화 (정리) (4) | 2025.01.17 |
[JAVA 기초] JAVA의 정석 - Ch.09 Java.lang 패키지와 유용한 클래스 (정리) (2) | 2025.01.16 |