[英]Java generic type bounded to classes with specific annotation
在 java 中,可以將泛型參數綁定到實現特定接口的類,因此可以進行以下操作
interface MyInterface {}
class MyClassA implements MyInterface {}
class MyBoundedClassA<T extends MyInterface>
現在,如果我想將參數綁定到帶有特定注釋的 class 的接口,例如:
interface @MyAnnotation {}
@MyAnnotation
class MyClassB {}
class MyBoundedClassB<T extends MyAnnotation> // NOT possible
是否有可能在 Java 中實現這樣的行為?
- - 編輯
根據要求添加真實世界的示例。 稍微修改域以使示例更易於理解。
有眾所周知的 jackson 庫用於序列化對象。 此庫不支持字符串以外的 map 鍵的序列化,因此無法開箱即用以下操作
class TimeRange {
LocalDateTime startDate;
LocalDateTime endDate;
}
class SportsmenActivities {
private Map<String, <TimeRange, List<Activity>> sportActivities;
}
在此示例中,外部 map 的鍵是“sportsmanCode”,如“andy”、“mike”、“john”。內部 Map 包含給定運動員在給定時間段內執行的活動。
因此,假設安迪慢跑了一天,而不是條目:
new SportsmanActivities().get("andy").put(TimeRange.of('2012-12-01,'2012-12-02'), List.with(new JoggingActivity)) // did some pseudo code here for readablity
現在正如所說的 Jackson 不會開箱即用地序列化,所以我編寫了通用模塊,它允許序列化這種復雜的 map。
要使用它,您需要做的是像這樣注釋您的“關鍵” class :
@KeySerializable
class TimeRange {
@MyMapKey
LocalDateTime startDate;
@MyMapKey
LocalDateTime endDate;
}
正如您所猜測的那樣,帶有@MyMapKey 注釋的字段將用於生成 MapKey。
現在我有一個 jackson class 的實現,它動態序列化作為“文本 map 密鑰”傳遞的所有內容,並用 @KeySerializable 注釋。 簽名如下
class MyMapKeySerializer<T> extends JsonSerializer<T> {
serialize (T keyToSerialize) {
// do magic
}
}
這可行,但我想將 T 限制為僅接受使用 @KeySerializable 注釋的類,因為僅對於此類類,此方法才有意義。 理想情況下,這將是這樣的:
class MyMapKeySerializer<T annotatedWith @KeySerializable> extends JsonSerializer<T> {
serialize (T keyToSerialize) {
// do magic
}
}
如果您的目標是斷言只接受帶注釋的類,那么您幾乎沒有解決方法:
parameter.getClass().isAnnotationPresent(MyAnnotation.class)
在運行時顯式檢查Checker Framework之類的工具插入到編譯器中,以類似於您要求的方式限制通用實例化。 它被實現為注解處理器,並提供正確使用的編譯時保證。
例如,您可以編寫class MyList<T extends @NonNull Object> {...}
。
Checker 框架使您能夠構建自己的檢查器,它可以強制執行您喜歡的有關@KeySerializable
的任何規則。 在您的情況下,規則可能非常簡單,您只需定義幾個類型限定符並使用子類型檢查器——至少一開始是這樣。
請注意,要使 Checker Framework 使用@KeySerializable
注釋工作,該注釋必須是類型注釋而不是聲明注釋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.