본 글은 책 자바의 정석을 ref 하여 요약한 글입니다.
제네릭스
컴파일 타임 시 타입 체크를 해주는 기능
다룰 객체의 타입을 미리 명시하여 형변환을 제거
추가적인 형변환을 하지 않아 성능이 향상된다.
컴파일 이후부터는 지정된 타입으로 바뀐다.
클래스와 메서드에 선언할 수 있다.
✔ 제한
static 에는 사용 불가능 (클래스 변수는 공유가 되는데, 인스턴스마다 제네릭 타입이 달라지므로)
new 배열 생성 코드 불가능 (new 연산자는 컴파일 타임 때 타입을 정확히 알아야 함)
✔ 형변환
지정된 제네릭 타입의 자손을 사용하면 형변환이 된다.
void add(T t)
*T가 부모일 경우 T의 자손도 인수로 사용할 수 있다.
✔ 제한된 지네릭
<T extends 부모 클래스>
부모 클래스와 자손 클래스들만 사용 가능
불필요한 다른 타입의 사용을 막는다.
사용할 수 있는 필드, 메서드는 부모 클래스의 것으로 제한된다.
✔ 제네릭 메서드
메서드의 리턴 타입 앞에 제네릭 타입을 지정하며 지역변수와 비슷하게 사용된다.
클래스의 제네릭 타입과는 관련이 없다. 메서드 내부에서만 사용된다.
<사용할 제네릭 타입> 리턴타입 메서드명(매개인자)
✔ 와일드카드
메서드의 리턴 타입, 매개 인자에 사용된다.
제네릭 타입이 불공변이기 때문에 사용한다.
* 불공변: 변하지 않는다.
* List<Object> list = new ArrayList<Integer>()
* 컴파일 안된다. 제네릭은 형변환 개념이 없다 <Object> 와 <Integer>는 아무 상관이 없다.
제네릭 형 변환
Clazz<String> <==> Clazz<Object> 형변환 // 불가능 (불공변)
Clazz<?> <==> Clazz<Object> 형변환 // 가능 (와일드 카드 사용 이유)
논제네릭과 제네릭 형변환 // 가능
메서드 인자 제네릭 타입
메서드는 타입이 달라야 오버 로딩이 가능한데, 지네릭 타입이 불공변이라 오버로딩이 되지 않는다.
void add(FruitBox<Fruit> f) // FruitBox<Fruit> 만 인수로 들어올 수 있다.
void add(FruitBox<Apple> f) // FruitBox<Apple> 만 인수로 들어올 수 있다.
오버로딩 불가능
어떤 제네릭 클래스가 들어올지 몰라서,
void add(FruitBox<?> f)
와일드카드는 메서드의 인수가 제네릭 타입만 다를 때 여러 제네릭 타입이 사용될 수 있도록 한다.
와일드카드를 사용하면 제네릭 타입이 무엇인지 알 수 없다.
정확한 제네릭 타입을 몰라서 확실하게 사용할 수 있는 기능만 사용한다.
메서드 인자로 와일드 카드를 사용할 때 메서드 구현부에서의 제한
(1) <?> 제한 없음
(2) <? extends T> T와 그 자손들만 가능
상한 제한으로 하게 되면 출력은 할 수 있고, 입력이 불가능하다.
출력: T의 출력 메서드를 자손 클래스들이 모두 상속했거나, 오버라이딩하여 가능하다.
입력: 제네릭 클래스가가 T의 하위 타입을 사용할 경우 T를 입력할 수 없다.
(3) <? super T> T와 그 조상들만 가능
하한 제한으로 하게 되면 반대로 출력을 할 수 없고, 입력만 할 수 있다.
입력: T와 그 조상들을 타입 변수로 제한하므로 T 타입은 무조건 입력이 될 수 있다.
출력: 상위 타입이 T타입의 메서드를 갖고 있지 않을 수 있다.
(가능한 경우에도 자바에서는 상한 제한에서 입력, 하한 제한에서의 출력을 불가능하게 막아둠)
✔ 제네릭 타입의 제거
하위 자바 버전과의 호환성을 유지하기위해 컴파일때 제거
열거형 (Enum)
서로 관련있는 상수를 편하게 관리하기 위해 등장
사용할 도메인 범위를 지정할 수 있다는 장점을 갖는다.
값뿐만 아니라 타입까지 사용하기 때문에 정확한 비교가 가능하다.
✔ 메서드
ordinal() 열거형 상수의 순서를 반환
name() 열거형 상수의 이름을 반환
values() 열거형 상수들을 배열에 담아서 반환
✔ 지정된 멤버 추가
enum Direction { EAST(-1), SOUTH(5), WEST(100), NORTH(10);
private final int value;
Direction(int value){
this.value = value;
}
불연속 열거형 값을 사용하기 위해선 생성자와 인스턴스 변수가 필요하다. (생성자는 private가 생략됨)
상수에 두가지 값을 사용하려면 두가지의 인스턴스 변수가 필요하다.
✔ 열거형 상수의 이해
열거형 상수 하나하나가 객체다.
객체의 주소가 바뀌지 않으므로 == 비교가 가능하다.
어노테이션
주석처럼 프로그램에 영향을 미치지 않으면서, 다른 프로그램에게 유용한 정보를 제공
✔ 메타 어노테이션 - 어노테이션을 위한 어노테이션
@Target
적용 가능한 대상을 지정
@Retention
어노테이션이 유지되는 기간
Runtime으로 지정시 Reflection을 통해 정보를 읽어서 처리할 수 있다.
@Inherited
자손 클래스에 상속되도록 한다.
@Repeatable
해당 어노테이션을 여러번 지정 가능
✔ 어노테이션 타입 지정
어노테이션에 선언된 메서드를 요소라고 한다.
요소들의 값을 빠짐없이 적어주어야 한다. (default가 지정되어 있으면 적어주지 않아도 된다.)
요소가 하나일 경우 이름 생략 가능
[규칙]
메서드 선언에는 매개변수를 사용할 수 없다.
예외를 선언할 수 없다.
메서드의 반환형에는 기본 타입, 문자열, 배열, 열거형, Class<> 클래스, 어노테이션
상수를 선언할 수도 있다.
'프로그래밍 > 자바' 카테고리의 다른 글
[JAVA] 14장. 람다, 스트림 (0) | 2022.07.31 |
---|---|
[JAVA] 13장. 쓰레드 (0) | 2022.07.31 |
[Java] equals()와 hashCode() 사용, HashSet에서의 활용 (0) | 2022.07.30 |
11장 컬렉션 프레임 워크 (0) | 2022.07.28 |
10장 날짜와 시간 & 형식화 (0) | 2022.07.28 |