[JAVA]지네릭, 열거형, 애너테이션

ggamang·2022년 9월 20일
0

JAVA&Spring

목록 보기
5/27

지네릭스

"컴파일" 시 타입을 체크해주는 기능
객체 타입 안정성을 높이고 형변환의 번거로움을 줄여주어 코드가 간결해짐

ArrayList tvList = new ArrayList();
Tv t = (Tv)tvList.get(0) // Object 타입 반환

ArrayList<TV> tvList = new ArrayList<TV>();
TV t = tvList.get(0); // 형변환 불필요

지네릭스 용어

Box<T'> : 지네릭 클래스
T : 타입 변수
Box : 원시 타입

class Box<T> {} // 지네릭 클래스 선언
Box<String> b - new Box<String>() // 대입된 타입: String

지네릭 타입과 다형성

참조 변수와 생성자의 대입된 타입은 일치해야 한다
지네릭 클래스 간의 다형성은 성립한다(대입된 타입은 일치해야 한다)

List<Tv> list = new ArrayList<Tv>();

매개변수의 다형성도 성립한다

class Product {}
class Tv extends Product {}
class Audio extends Product {}

ArrayList<Product> list = new ArrayList<Product>();
list.add(new Product());
list.add(new Tv());		// 가능
list.add(new Audio());	// 가능

Iterator<'E>
HashMap<K,V>

제한된 지네릭 클래스

extends로 대입할 수 있는 타입을 제한
인터페이스인 경우에도 'extends'를 사용한다

class Fruit implements Eatable { // 내용 생략 }
class Apple extends Fruit {}
interface Eatable {}

class FruitBox<T extends Fruit & Eatable> // Fruit 의 자손만 타입으로 지정

지네릭스의 제약

타입 변수에 대입은 인스턴스 별로 다르게 가능
1. static 멤버에 타입 변수 사용 불가
2. 배열 생성할 때 타입 변수 사용 불가하다. 타입 변수로 배열 생성은 가능하다 (new 다음에 타입변수 쓸 수 없다)

와일드 카드 '<?>'

하나의 참조 변수로 대입된 타입이 다른 객체를 참조 가능하다
☞ 하나의 참조변수로 서로 다른 타입이 대입된 여러 지네릭 객체를 다루기 위함

'<? extends T>' : 와일드 카드의 상한 제한. T와 그 자손들만 가능
'<? super T>' : 와일드 카드의 하한 제한. T와 그 조상들만 가능
'<?>' : 제한없음. 모든 타입이 가능하다

메서드의 매개변수에 와일드 카드 사용 가능하다

지네릭 메서드

지네릭 타입이 선언된 메서드로, 타입 변수는 메서드 내에서만 유효하다
메서드를 호출할 때마다 타입을 대입해야 한다(대부분 생략 가능)
메서드를 호출할 때 타입을 생략하지 않을 때는 클래스 이름 생략 불가하다
☞ 메서드를 호출할 때마다 다른 지네릭 타입을 대입할 수 있게 한 것

지네릭 타입의 형변환

지네릭 타입과 원시 타입 간의 형변환은 권고X
와일드 카드가 사용된 지네릭 타입으로는 형변환 가능

Box<? extends Object> wBox = new Box<String>();

지네릭 타입의 제거

컴파일러는 지네릭 타입을 제거하고 필요한 곳에 형변환을 넣는다 (하위호환성 고려)

열거형

관련된 상수들을 같이 묶어 놓은 것
타입에 안전한 열거형 제공(값, 타입 모두 체크)
열거형 상수 비교에 ==와 compareTo() 사용 가능

enum 열거형이름 { 상수명1, 상수명2, ... }

모든 열거형은 Enum의 자손이다
불연속적인 열거형 상수의 경우, 원하는 값을 괄호 안에 엏는다

enum Direction {EAST(1), SOUTH(6)}

단, 괄호 사용하려면 인스턴스 변수와 생성자 새로 추가해줘야 한다

애너테이션

주석처럼 프로그래밍 언어에 영향 미치지 않으며 유용한 정보를 제공

표준 애너테이션

@Override
오버라이딩을 올바르게 했는지 컴파일러가 체크

@Deprecated
앞으로 사용하지 않을 것을 권장하는 필드, 메서드에 붙음

@FunctionalInterface
함수형 인터페이스에 붙이면, 컴파일러가 올바르게 작성했는지 체크
하나의 추상메서드만 가져야 한다

@SuppressWarnings
컴파일러의 경고메시지가 나타나지 않게 억제한다.
괄호 안에 억제하고자 하는 경고의 종류를 문자열로 지정해준다

메타 애너테이션

애너테이션을 위한 애너테이션

@Target
애너테이션을 정의할 때, 적용 대상을 지정하는데 사용한다

@Retention
애너테이션이 유지되는 기간을 지정하는데 사용
유지정책: SOURCE, CLASS, RUNTIME

@Doucmented
javadoc으로 작성한 문서에 포함시키기 위해 붙임

@Inherited
애너테이션을 자손 클래스에 상속하고자 할 때 붙인다

@Repeatable
반복해서 붙일 수 있는 애너테이션을 정의할 때 사용

애너테이션 사용자 정의

애너테이션의 메서드는 추상 메서드이며, 애너테이션을 적용할 때 지정한다

@interface 애너테이션이름 {
	타입 요소이름();
}

애너테이션의 요소

기본값 지정에는 null을 사용할 수 없다
요소가 하나이고 이름이 value일 때는 요소 이름을 생략할 수 있다
요소의 타입이 배열인 경우 괄호 {}를 사용해야 한다

요소 선언 시 규칙
1. 요소의 타입은 기본형, String, enum, 애너테이션, Class만 허용
2. 괄호 안에 매개변수 선언 불가
3. 예외 선언 불가
4. 요소를 타입 매개변수(<T'>)로 정의 불가

Annotation

모든 애너테이션의 조상이지만 상속은 불가하다(=인터페이스)
추상메서드를 구현하지 않고도 사용할 수 있다

마커 애너테이션

요소가 하나도 정의되지 않은 애너테이션

0개의 댓글