Introduction
In my article "Using a hashmap in a custom annotation" I explained how to use a HashMap in an annotation using an Enum Constant.
Nested annotations can also be used to map key-value pairs.
Annotations
Two customs annotations are required. The first annotation (e.g. MapItem
) containing a key-value pair and the second annotation (e.g. MapItems
) containing a list of MapItem annotations.
Custom Annotation @MapItem
The annotation @MapItem
represents a single key-value pair.
@Target(ElementType.FIELD)
public @interface MapItem {
String key();
String value();
}
Custom Annotation @MapItems
The annotation @MapItems
defines a list of MapItem.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MapItems {
MapItem[] items();
}
Functional Test
The list of @MapItem
annotations are set in the @MapItems annotation.
class ExampleDto {
@MapItems(items = {
@MapItem(key = "1", value = "MALE"),
@MapItem(key = "2", value = "FEMALE"),
@MapItem(key = "6", value = "DIVERS")
})
public String salutation;
}
The MapItemsTest tests the MapItems annotation. The test is done on the salutation field.
To demonstrate how the list of @MapItem
can be used, I create a HashMap from @MapItem
and compare it to an expected HashMap.
class MapItemsTest {
@Test
void testMapItems() throws NoSuchFieldException {
Field field = ExampleDto.class.getDeclaredField("salutation");
field.setAccessible(true);
MapItems annotation = field.getAnnotation(MapItems.class);
Map<String, String> mappingItems = Arrays
.stream(annotation.items())
.collect(
Collectors.toMap(
MapItem::key,
MapItem::value
)
);
assertEquals(
new HashMap<>() {{
put("1", "MALE");
put("2", "FEMALE");
put("6", "DIVERS");
}},
mappingItems
);
}
}
Conclusion
Pro
It is a smart solution and easy to implement.
Contra
If the key-value pairs are to be used in a validator, for example, they must be fetched indirectly.
Full example
https://github.com/alaugks/article-annotation-key-value-pairs
Top comments (0)