작성중

Generics

컴파일 시의 타입 체크를 해주는 기능입니다.

컴파일 시 타입 체크를 하는 이유

  1. 객체의 타입을 컴파일 시에 체크하면 객체 타입의 안정성이 높아집니다.
    • 의도하지 않은 타입의 객체가 저장되는 것을 막을 수 있습니다.
    • 저장된 객체를 꺼내올 때 강제 형변환을 줄일 수 있습니다.
  2. 형변환의 번거로움이 줄어듭니다.

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 box = new Box<>("my first item"); box.getItem(); } }


### Generics는 static에 사용할 수 없습니다. 
- Generics는 인스턴스 변수로 취급되기 때문에 `static`은 사용할 수 없습니다.

### Generics는 배열에 사용할 수 없습니다.
- Generics는 배열을 생성할 수 없습니다. 아래와 같은 코드는 에러가 납니다.
  - ` T[] genArray = new T[4]; `
  - `new`를 하기 위해선 클래스가 미리 컴파일 되어 있어야 하는데 Generics는 컴파일 타임에 타입이 정해지므로 위 코드는 에러입니다.
  - 아래처럼 메소드에 매개변수로 받는 것은 가능합니다.

public class Main { public static void main(String[] args) { List a2 = Arrays.asList(new Integer[] {1,2,3,4,5}); sum(a2); }

static void sum(List<? extends Number> list) {
	double value = 0;
	for (Number v : list){
    value += v.doubleValue();
}
} }
  - 아래처럼 클래스의 인스턴스 변수는 가능합니다.

class Box { private T[] items; private List items; }


### Generics 메서드
- static

class Box{ static void sort(List list, Comparator<? super T> c) { } }


### 자바의 Generics를 사용한 예 1
- Comparator도 Generics로 만들어진 인터페이스다.

@FunctionalInterface public interface Comparator { }


### 자바의 Generics를 사용한 예 2 ( <?> 와 <Object> | Generics의 와일드카드 )
- `EMPTY`의 `<?>`를 사용하면 `<T>`로 형변환이 가능해집니다.
- `<Object>`로 선언하면 `<T>`로 형변환은 불가능합니다.

public final class Optional { private static final Optional<?> EMPTY = new 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가 있습니다.

댓글남기기