[Java Basic] ch12.Annotation
작성중
Generics
컴파일 시의 타입 체크를 해주는 기능입니다.
컴파일 시 타입 체크를 하는 이유
- 객체의 타입을 컴파일 시에 체크하면 객체 타입의 안정성이 높아집니다.
- 의도하지 않은 타입의 객체가 저장되는 것을 막을 수 있습니다.
- 저장된 객체를 꺼내올 때 강제 형변환을 줄일 수 있습니다.
- 형변환의 번거로움이 줄어듭니다.
Generics 사용법
-
T
는 타입변수라고 합니다. ``` class Box{ private T item; public Box(T item){ this.item = item; } public T getItem(){ return this.item; } }
class Main{
public static void main(String args[]){
Box
### Generics는 static에 사용할 수 없습니다.
- Generics는 인스턴스 변수로 취급되기 때문에 `static`은 사용할 수 없습니다.
### Generics는 배열에 사용할 수 없습니다.
- Generics는 배열을 생성할 수 없습니다. 아래와 같은 코드는 에러가 납니다.
- ` T[] genArray = new T[4]; `
- `new`를 하기 위해선 클래스가 미리 컴파일 되어 있어야 하는데 Generics는 컴파일 타임에 타입이 정해지므로 위 코드는 에러입니다.
- 아래처럼 메소드에 매개변수로 받는 것은 가능합니다.
public class Main {
public static void main(String[] args) {
List
static void sum(List<? extends Number> list) {
double value = 0;
for (Number v : list){
value += v.doubleValue();
}
} }
- 아래처럼 클래스의 인스턴스 변수는 가능합니다.
class Box
### Generics 메서드
- static
class Box
### 자바의 Generics를 사용한 예 1
- Comparator도 Generics로 만들어진 인터페이스다.
@FunctionalInterface
public interface Comparator
### 자바의 Generics를 사용한 예 2 ( <?> 와 <Object> | Generics의 와일드카드 )
- `EMPTY`의 `<?>`를 사용하면 `<T>`로 형변환이 가능해집니다.
- `<Object>`로 선언하면 `<T>`로 형변환은 불가능합니다.
public final class Optional
private final T value;
private Optional() {
this.value = null;
}
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
---
# Enum
### 기본형
```java
enum Card {
CLOVER(1), HEART(2), DIAMOND(3), SPADE(4);
private final int score;
Card(int score) { this.score = score; }
public int getScore() { return score; }
}
추상 메서드 추가
enum Transportation {
BUS(100){
int fare(int distance) { return distance * BASIC_FARE; }
},
TRAIN(150){
int fare(int distance) { return distance * BASIC_FARE; }
},
SHIP(200){
int fare(int distance) { return distance * BASIC_FARE; }
},
AIRPLANE(300){
int fare(int distance) { return distance * BASIC_FARE; }
};
Transportation(int basicFare) {
BASIC_FARE = basicFare;
}
abstract int fare(int distance);
protected final int BASIC_FARE;
}
Annotation
프로그래밍에 영향을 주지 않으면서 다른 프로그램에 유용한 정보를 제공합니다.
예를 들어, 소스중에서 특정 메소드만 테스트를 하길 원한다면 @Test
를 그 메서드에 붙이면 됩니다.
이 메서드를 테스트 해야한다 라는 걸 JUnit에게 알려주는 역할일 뿐 프로그램 자체엔 아무런 영향도 미치지 않습니다.
@Type
애너테이션 정의할 때, 적용대상 지정에 사용합니다.
- TYPE : 클래스
- FIELD : Instance Variable
- METHOD :
public enum ElementType {
/** Class, interface (including annotation interface), enum, or record
* declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation interface declaration (Formerly known as an annotation type.) */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*/
TYPE_PARAMETER,
/**
* Use of a type
*/
TYPE_USE,
/**
* Module declaration.
*/
MODULE,
/**
* Record component
*/
RECORD_COMPONENT;
}
@Retention
- SOURCE : 소스 파일에 존재, 클래스 파일에는 존재하지 않습니다. 컴파일시에만 사용됨.
- CLASS : 클래스 파일에 존재, 런타임시엔 존재하지 않습니다.
- RUNTIME : 클래스 파일에 존재, 런타임까 존재합니다.
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
}
Marker Annotation
아무런 요소가 정의되지 않은 애너테이션으로 그저 컴파일러에게 이게 어떤 대상인지 알리는 용도입니다
대표적으로 @Test
가 있습니다.
댓글남기기