在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。现在我有一个 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
提交
取消