當註釋類型是嵌套的通用接口時,看起來TYPE_USE註釋不能通過反射進行訪問。當嵌套類型時,TYPE_USE註釋會丟失通用接口
請注意下面的例子:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;
public class LostAnnotation {
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface SomeTypeAnnotation {
}
@SomeTypeAnnotation Map<String, String> map;
@SomeTypeAnnotation Entry<String, String> entry;
public static @SomeTypeAnnotation Entry<String, String> someMethod(
@SomeTypeAnnotation Map<String, String> map,
@SomeTypeAnnotation Entry<String, String> entry) {
return null;
}
public static void main(String[] args) throws Exception {
Class<LostAnnotation> clazz = LostAnnotation.class;
Method method = clazz.getMethod("someMethod", Map.class, Entry.class);
AnnotatedType[] types = method.getAnnotatedParameterTypes();
print("map field", clazz.getDeclaredField("map").getAnnotatedType());
print("map parameter", types[0]);
print("entry field", clazz.getDeclaredField("entry").getAnnotatedType());
print("entry parameter", types[1]);
print("entry return type", method.getAnnotatedReturnType());
}
static void print(String title, AnnotatedType type) {
System.out.printf("%s: %s%n", title, Arrays.asList(type.getAnnotations()));
}
}
的預期上述代碼的輸出是
map field: [@LostAnnotation$SomeTypeAnnotation()]
map parameter: [@LostAnnotation$SomeTypeAnnotation()]
entry field: [@LostAnnotation$SomeTypeAnnotation()]
entry parameter: [@LostAnnotation$SomeTypeAnnotation()]
entry return type: [@LostAnnotation$SomeTypeAnnotation()]
然而,上述代碼的實際輸出是
map field: [@LostAnnotation$SomeTypeAnnotation()]
map parameter: [@LostAnnotation$SomeTypeAnnotation()]
entry field: []
entry parameter: []
entry return type: []
可以從Map
接口的每次使用中正確檢索註釋。但是,在接口的每個用法上,無論是字段,返回類型還是參數,註釋都會丟失。我唯一的解釋是,Entry
接口是嵌套在Map
接口內的。
我在win64上運行最新的oracle JDK(8u121)上面的例子。我做錯了什麼,或者這可能是一個錯誤?
爲了便於閱讀,我的註釋是嵌套的。使其成爲頂級界面不會改變任何內容。
我測試了一下代碼,並在代碼中找不到任何錯誤。所以我同意kriegaex,這個接縫是jvm中的一個bug。 –