[英]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.