2017-02-28 89 views
10

當註釋類型是嵌套的通用接口時,看起來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)上面的例子。我做錯了什麼,或者這可能是一個錯誤?

爲了便於閱讀,我的註釋是嵌套的。使其成爲頂級界面不會改變任何內容。

+2

我測試了一下代碼,並在代碼中找不到任何錯誤。所以我同意kriegaex,這個接縫是jvm中的一個bug。 –

回答

0

我不知道我是否可以作爲可信來源(絕對不是官方的),但IMO是JDK中的一個缺陷或至少是缺點(未完全實現)。

你沒有做錯任何事 - 或者我們都錯了,這仍然是可能的。

正如羅素所說:

該意見已被廣泛持有的事實是任何證據表明,它不是完全荒謬的。

;-)