在java中,可以將通用參數綁定到實現特定接口的類,因此以下是可能的interface MyInterface {}class MyClassA implements MyInterface {}class MyBoundedClassA<T extends MyInterface>現在,如果我想將參數綁定到用特定注釋注釋的類,例如:interface @MyAnnotation {}@MyAnnotationclass MyClassB {}class MyBoundedClassB<T extends MyAnnotation> // NOT possible在Java中是否可以實現這樣的行為?- - 編輯根據要求添加現實世界的例子。稍微修改域以使示例更容易理解。有一個眾所周知的杰克遜庫用于序列化對象。該庫不支持字符串以外的映射鍵的序列化,因此以下內容不可能開箱即用class TimeRange { LocalDateTime startDate; LocalDateTime endDate;}class SportsmenActivities { private Map<String, <TimeRange, List<Activity>> sportActivities;}在此示例中,外部地圖的鍵是“sportsmanCode”,如“andy”、“mike”、“john”。內部地圖包含給定運動員在給定時間段內執行的活動。假設安迪慢跑了一天,條目如下:new SportsmanActivities().get("andy").put(TimeRange.of('2012-12-01,'2012-12-02'), List.with(new JoggingActivity)) // did some pseudo code here for readablity現在正如所說的杰克遜不會將其序列化開箱即用,所以我編寫了通用模塊,它允許序列化此類復雜的地圖。要使用它,您需要做的就是像這樣注釋您的“關鍵”類:@KeySerializableclass TimeRange { @MyMapKey LocalDateTime startDate; @MyMapKey LocalDateTime endDate;}您可以猜測用@MyMapKey注釋的字段將用于生成MapKey?,F在我有一個 jackson 類的實現,它動態地序列化作為用 @KeySerialized 注釋的“文本映射鍵”傳遞的所有內容。簽名如下 class MyMapKeySerializer<T> extends JsonSerializer<T> { serialize (T keyToSerialize) { // do magic } }這是可行的,但我想限制 T 只接受用 @KeySerialized 注釋的類,因為只有對于此類類,此方法才有意義。理想情況下,這將是這樣的: class MyMapKeySerializer<T annotatedWith @KeySerializable> extends JsonSerializer<T> { serialize (T keyToSerialize) { // do magic } }
2 回答

嗶嗶one
TA貢獻1854條經驗 獲得超8個贊
如果您的目標是斷言僅接受帶注釋的類,那么您幾乎沒有解決方法選項:
編寫一個在編譯時執行斷言的注釋處理器(參見@NonNull等如何工作)。這是一項有趣的工作,但并不簡單,因為編譯/類型系統對于許多經驗豐富的 Java 開發人員來說是全新的。
使用某種形式的 AOP(AspectJ、Spring AOP 等)來“建議”帶有裝飾器的所有帶注釋的方法,該裝飾器的職責是斷言參數具有相同的注釋。
使用在運行時顯式檢查
parameter.getClass().isAnnotationPresent(MyAnnotation.class)

守候你守候我
TA貢獻1802條經驗 獲得超10個贊
像Checker Framework這樣的工具會插入編譯器中,以類似于您所請求的方式限制通用實例化。它作為注釋處理器實現,并提供正確使用的編譯時保證。
例如,您可以寫class MyList<T extends @NonNull Object> {...}
。
Checker Framework 使您能夠構建自己的檢查器,它強制執行您喜歡的任何規則@KeySerializable
。在您的情況下,規則可能非常簡單,您只需定義幾個類型限定符并使用子類型檢查器- 至少一開始是這樣。
請注意,要使 Checker 框架使用注釋工作@KeySerializable
,該注釋必須是類型注釋而不是聲明注釋。
添加回答
舉報
0/150
提交
取消