Introduction
There may be a requirement to define key-value pairs in an annotation in order to perform a mapping based on keys or/and values.
In this case a HashMap would be the first choice. However, annotations do not support the type HashMap. A HashMap can be used with the Enum type, which is supported by annotations.
In my article "Creating a custom Jackson JsonSerializer and JsonDeserializer for mapping values", I create the custom annotation @MappingTable
to use key-value pairs for bidirectional mapping in a custom JsonSerializer and JsonDeserializer.
Enum Constant
The Maps
enumeration type contains the constant SALUTATION_MAP
. The HashMaps are defined in these constants using Map.of()
. Alternatively, new HashMap<>()
can be used.
import java.util.Map; public enum Maps { SALUTATION_MAP(Map.of("1", "MALE", "2", "FEMALE", "6", "DIVERS")); private final Map<String, String> map; Maps(Map<String, String> map) { this.map = map; } public Map<String, String> getMap() { return this.map; } }
Custom Annotation @MapItems
The enumeration type Maps
is set as the type in the annotation.
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface MapItems { Maps map(); }
Functional Test
The enum constants are referenced in the @MapItems
annotation.
class ExampleDto { @MapItems(map = Maps.SALUTATION_MAP) public String salutation; }
The MapItemsTest
tests the MapItems annotation. The test is done on the salutation
field.
class MapItemsTest { @Test void testEnumConstants() throws NoSuchFieldException { Field field = ExampleDto.class.getDeclaredField("salutation"); field.setAccessible(true); MapItems annotation = field.getAnnotation(MapItems.class); assertSame(Maps.SALUTATION_MAP.getMap(), annotation.map().getMap()); } }
Conclusion
Pro
- Simple implementation
- Reuse of the HashMap, for example, when validating a property of a payload, validating fields in a DTO or collecting key-value pairs in a response.
Contra
–
Full example
https://github.com/alaugks/article-annotation-key-value-pairs
Top comments (0)