Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多个子类的反射方法缓存_Java_Caching_Reflection - Fatal编程技术网

Java 多个子类的反射方法缓存

Java 多个子类的反射方法缓存,java,caching,reflection,Java,Caching,Reflection,我有一个abstract类,它由多个具体类扩展。 抽象类初始化块获取当前类层次结构的所有方法,搜索特定的带注释的方法 ConcreteClass2 > ConcreteClass1 > AbstractClass OtherConcrete1 > AbstractClass { ... 最终列表方法=新的ArrayList(16); Clazz Clazz=getClass(); while(clazz!=Object.class){ for(最终方法:clazz.getD

我有一个
abstract
类,它由多个具体类扩展。 抽象类初始化块获取当前类层次结构的所有方法,搜索特定的带注释的方法

ConcreteClass2 > ConcreteClass1 > AbstractClass
OtherConcrete1 > AbstractClass

{
...
最终列表方法=新的ArrayList(16);
Clazz Clazz=getClass();
while(clazz!=Object.class){
for(最终方法:clazz.getDeclaredMethods()){
if(方法.isAnnotationPresent(MyAnnotation.class)){
方法:添加(方法);
}
}
clazz=clazz.getSuperclass();
}
METHODS.put(getClass(),METHODS);
...
}
这些具体类在web/应用服务器中实例化,并在
Servlet
s中使用

由于反射本身并不是最快的,而且我不想每次实例化具体类型时都重复扫描(
new
),缓存带注释的
方法的最佳策略是什么


我实际上使用的是
ConcurrentHashMap
作为
如果您使用的是Java 8,请使用
ComputeFabSent
避免重新计算带有注释的方法集:

private static final ConcurrentMap<Class<?>,List<Method>> METHODS = new ConcurrentHashMap<>();
...
Clazz<?> clazz = getClass();
METHODS.computeIfAbsent(clazz, c -> findMethods(c));
...
private static List<Method> findMethods(Class<?> clazz) {
    final List<Method> methods = new ArrayList<>(16);
    while (clazz != Object.class) {
        for (final Method method : clazz.getDeclaredMethods()) {
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                methods.add(method);
            }
        }
        clazz = clazz.getSuperclass();
    }
    return methods;
}
private static final ConcurrentMap clazz=getClass();
方法:ComputeFabSent(clazz,c->findMethods(c));
...
私有静态列表findMethods(类clazz){
最终列表方法=新的ArrayList(16);
while(clazz!=Object.class){
for(最终方法:clazz.getDeclaredMethods()){
if(方法.isAnnotationPresent(MyAnnotation.class)){
方法:添加(方法);
}
}
clazz=clazz.getSuperclass();
}
返回方法;
}

这将缓存每个类的方法,并避免为同一类重新计算
List

在web应用程序启动后,可能会对您的注释进行一次性扫描(类似于Spring)。@AndrewS我无法修改应用程序启动。不幸的是,代码库超过了JDK 1.6。我有相当大的禁忌。如果你有番石榴,你可以用一个无限的
缓存来代替。
private static final ConcurrentMap<Class<?>,List<Method>> METHODS = new ConcurrentHashMap<>();
...
Clazz<?> clazz = getClass();
METHODS.computeIfAbsent(clazz, c -> findMethods(c));
...
private static List<Method> findMethods(Class<?> clazz) {
    final List<Method> methods = new ArrayList<>(16);
    while (clazz != Object.class) {
        for (final Method method : clazz.getDeclaredMethods()) {
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                methods.add(method);
            }
        }
        clazz = clazz.getSuperclass();
    }
    return methods;
}