2013-07-29 4 views
0

가능합니까?일반 클래스 유형 (특수 효과)

class MyService<T> { 

    @MyAnnotation(T.class) 
    private String myProperty; 
} 

컴파일러가 마음에 들지 않습니다. 어떻게해야합니까?

UPDATE

나는 내가 할 수 없습니다 발견했다. Error setting annotation value as Class<?> from a constant, why?을 참조하십시오.

+1

시험해보기 : private T myProperty; – Veera

+0

죄송합니다. 실제로'T.class' 부분에 대해 질문했습니다. –

답변

6

그건 불가능합니다.

주석에 대한 매개 변수는 컴파일시 상수 값 (예 : 문자열, 숫자 상수 또는 클래스 리터럴, 예 : User.class)이어야하며 컴파일시 정의되지 않은 일반 매개 변수 T이 있어야합니다. T는 형식 매개 변수의 경우

은 또한, 다음 T.class 인해 유형의 삭제이라는 것을 (herehere 참조), 어떤 상황에서 유효한 자바 코드가 아닙니다. 런타임에 유형 매개 변수 T의 클래스가 무엇인지 알아야하는 경우 몇 가지가 있습니다. 예를 들어 :

class Repository<T> { 
    private final Class<T> type; 
    Repository(Class<T> type) { this.type = type; } 
    T load(int id) { ... can use type here ... } 
} 

또한, 구글 구아바 ( herehere 참조) 및/또는 Guice을 ( herehere 참조) 확인하십시오. 이 두 라이브러리는 런타임시 T으로 표시된 클래스를 생성자에서 전달하지 않고 삽입하거나 다른 방법으로 결정할 수있는 방법을 제공합니다.

이 라이브러리에서 사용하는 기술은 주어진 Class<?>의 유형 매개 변수에 대한 정보에 액세스 할 수는 없지만 해당 클래스의 수퍼 유형에 대한 정보에 액세스 할 수 있다는 사실에 기반합니다. 따라서 abstract class Service<T>라고하고 class MyService extends Service<String>이있는 경우 Class<MyService>을 사용하여 getGenericSuperclass()을 호출하고 그 결과를 사용하여 인 T의 값을 얻을 수 있습니다. 이 작업은 지루하고 오류가 발생하기 쉽기 때문에 라이브러리를 사용하여 작업하십시오.

1

불가능 유형으로 인해이 가능합니다. 이런 식으로 할 수 있습니다.

class MyConcreteService extends MyService<String> { 

    @MyAnnotation(String.class) 
    private String myProperty; 
} 

제네릭 매개 변수가 알려진 서비스의 구체적인 인스턴스를 생성 한 다음 클래스가 알려진대로 해당 주석을 사용할 수 있습니다. 네, 지루한 일입니다.