簡體   English   中英

使用運行時給定的類型創建通用映射

[英]Create a generic map using type given at runtime

標題可能有點難以理解,但讓我簡單地描述一下我的問題。

我們假設我有一個這樣的注釋:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Identifier {

}

現在,我創建了一個用它來注釋其任何字段的類:

public class Student {
    private String name;
    private String surname;
    @Identifier
    private String idNumber;
    ...
}

最后,在運行時,我想創建一個鍵類型為typeof(field annotated with @Identifier)Map typeof(field annotated with @Identifier)和值類型Student 請注意,任何字段都可以使用@Identifier進行注釋。

有任何想法嗎?

編輯

好的,讓我澄清一點:

class Student {
    private String name;
    private String surname;
    @Identifier
    private String idNumber;
}

class Foo {
    @Identifier
    private Integer x;
}

//  Now, what I want to have are two maps:

SortedMap students;     //  key type: String
                        //  value type: Student
SortedMap foos;         //  key type: Integer
                        //  value type: Foo

提前致謝!

我還不確定你想做什么。

在運行時我想創建一個鍵類型為typeof的Map(帶有@Identifier注釋的字段)和值類型Student

您可以創建原始MapMap<Object, Object> 您可以獲取使用@Identifier注釋的字段類型。 我不確定你對學生價值類型是什么意思所以我認為你的意思是Student類型,即。 它的Class對象。

public static void main(String[] args) throws Exception {
    Class<?> clazz = Student.class;
    Map<Object, Object> map = new HashMap<>();
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
        Identifier annotation = field.getAnnotation(Identifier.class);
        if (annotation != null) {
            map.put(field.getType(), clazz);
        }
    }
    System.out.println(map);
}

在您的問題中使用您的示例類,這將打印出來

{class java.lang.String=class com.spring.Student}

因此,帶注釋的字段類型將映射到類類型。

您將無法擁有Map<String,Student>因為您在編譯時不知道String類型(可能甚至不是Student )。 你可以嘗試強制轉換,但是你要為自己設置一些ClassCastException

因此,您將獲得一個方法(在我的示例中為myMethod ),該方法將傳遞可能包含使用@Identifier注釋的字段的對象。

很抱歉破解了你的泡泡但是沒有辦法在運行時保留通用信息。 你可以得到的最接近的是Map<Field, Class<?>> ,它保存了你想要的類型的鍵值對。 這是你如何做到的:

public Map<Field, Class<?>> myMethod(Object obj) {
    Map<Field, Class<?>> result = new HashMap<Field, Class<?>>();
    for(Field field : obj.getClass().getDeclaredFields()) {
        Identifier identifier = field.getAnnotation(Identifier.class);
        if(identifier != null) {
            result.put(field, obj.getClass());
            return result;
        }
    }
    return result;
}

在我的示例中,結果將是空Map或具有一個鍵值對的Map 我建議您應該為結果使用單獨的類型而不是Map 當然,如果你想要一個Field以外的東西,你可以篡改代碼,例如你可以使用FieldgetType()getGenericType()方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM