타입 선언부에도 사용할 수 있게 됨중복해서 사용할 수 있게 됨TYPE_PARAMETER
TYPE_PARAMETER}) 타입 변수에만 사용할 수 있다.@Retention(RetentionPolicy.RUNTIME) // 이 애노테이션 정보를 언제까지 유지할 것인가
@Target(ElementType.TYPE_PARAMETER) // 이 애노테이션을 사용할 곳
public @interface Chicken {
}
public static <@Chicken C>/*타입 파라미터*/ void print(C c/* 타입 */){
	System.out.println(c);
}
TYPE_USE
TYPE_USE})타입 변수를 포함해서 모든 타입 선언부에 사용할 수 있다.@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE})
public @interface Pizza {
}
public static <@Pizza C>/*타입 파라미터*/ void println(@Pizza C c/* 타입 */){
	System.out.println(c);
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@Repeatable(ChickenContainer.class)
public @interface Chicken {
    String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface ChickenContainer {
    Chicken[] value();
}
@Chicken("양념")
@Chicken("마늘")
@Chicken("간장")
@Chicken("후라이드")
public class AppForJava8Annotation {
    public static void main(String[] args) {
        Chicken[] chickens = AppForJava8Annotation.class.getAnnotationsByType(Chicken.class);
        Arrays.stream(chickens).forEach(c -> {
            System.out.println(c.value());
        });
        System.out.println(" ");
        ChickenContainer chickenContainer = AppForJava8Annotation.class.getAnnotation(ChickenContainer.class);
        Arrays.stream(chickenContainer.value()).forEach(c -> {
            System.out.println(c.value());
        });
    }
}