For some reason, I need to cache entries of classes and their field or field name using reflection.
private static final Map<Class<?>, String> ID_ATTRIBUTE_NAMES = new WeakHashMap<>();
private static String findIdAttributeName(final Class<?> clazz) {
Objects.requireNonNull(clazz, "clazz is null");
for (Class<?> current = clazz; current != null; current = current.getSuperclass()) {
for (final Field field : current.getDeclaredFields()) {
if (field.getAnnotation(Id.class) != null) {
return field.getName();
}
if (field.getAnnotation(EmbeddedId.class) != null) {
return field.getName();
}
}
}
throw new RuntimeException("unable to find an id attribute from " + clazz);
}
private static String idAttributeName(final Class<?> clazz) {
Objects.requireNonNull(clazz, "clazz is null");
return ID_ATTRIBUTE_NAMES.computeIfAbsent(clazz, BaseMappedHelper::findIdAttributeName);
}
The reason that I didn't define the map as Map<Class<?>, Field>
is that a Field
instance might strongly refer the its declaring class.
Is there any other way using other than using the field name of String
?
You can use Apache or Spring BeanUtils (https://commons.apache.org/proper/commons-beanutils/) that is optimized with cache.
Maybe you need BeanMap to interacte with your objects as map. https://commons.apache.org/proper/commons-collections/javadocs/api-3.2.2/org/apache/commons/collections/BeanMap.html
But you don't need a weak reference because number of fields is not so huge.