这是缓存反射数据的正确方法吗?

时间:2016-01-06 12:24:06

标签: java reflection

我正在处理一些我用hibernate实现的web服务。问题是我需要访问实体表的名称(比如@Table中的那些(" Table_A"))。 代码生成,所以我不能改变实体类本身给我我需要的东西。

这就是我到目前为止所做的事情:

public static
<T extends Entity<K>, K extends Serializable>
String getTableName(Class<T> objClass) {
    Table table = objClass.getAnnotation(Table.class);
    return (table != null)? table.name() : null;
}

然而,经过一些研究后,我发现反射并不是最好的表现方式,而且由于这种方法会被大量调用,我正在寻找另一种方法。

我试图遵循这里给出的建议: Performance of calling Method/Field.getAnnotation(Class) several times vs. Pre-caching this data in a Map

这就是我提出的:

public final class EntityUtils {
    private static HashMap<String, String> entityCache;

    private EntityUtils() {
        entityCache = new HashMap<String, String>();
    }

    public static
    <T extends Entity<K>, K extends Serializable>
    String getTableName_New(Class<T> objClass) {
        String tableName = entityCache.get(objClass.getCanonicalName());

        if (tableName == null) {
            Table table = objClass.getAnnotation(Table.class);

            if (table != null) {
                tableName = table.name();
                entityCache.put(objClass.getCanonicalName(), tableName);
            }
        }

        return tableName;
    }
}

但是,我对此并不确定。将反射数据缓存在静态地图中是一个好主意吗?有没有其他方法可以实现这个目标?

1 个答案:

答案 0 :(得分:2)

理想情况下,我会使用带有弱键的Guava缓存,这样您就不会保留对类对象的任何引用,以防您使用某些高级ClassLoader魔法。

LoadingCache<Class<?>, String> tableNames = CacheBuilder.newBuilder()
       .weakKeys()
       .build(
           new CacheLoader<Class<?>, String>() {
             public String load(Class<?> key) {
                 Table table = objClass.getAnnotation(Table.class);
                 return table == null ? key.getSimpleName() : table.name();
             }
           });

用法:

String tablename = tableNames.get(yourClass);

请参阅:Caches Explained

另一方面:注释也由JDK缓存,所以你以前的方法可能很好