Java 有没有更有效的方法来获取带注释的方法?

Java 有没有更有效的方法来获取带注释的方法?,java,reflection,Java,Reflection,我启动了一个“为了好玩,没人知道,没人关心”的开源项目() 在一个地方,我需要得到一个类的带注释的方法 还有比这更有效的方法吗?我的意思是不需要遍历每个方法 for (final Method method : cls.getDeclaredMethods()) { final HandlerMethod handler = method.getAnnotation(HandlerMethod.class); if (handler != null) {

我启动了一个“为了好玩,没人知道,没人关心”的开源项目()

在一个地方,我需要得到一个类的带注释的方法

还有比这更有效的方法吗?我的意思是不需要遍历每个方法

for (final Method method : cls.getDeclaredMethods()) {

    final HandlerMethod handler = method.getAnnotation(HandlerMethod.class);
        if (handler != null) {
                return method;
          }
        }

不,但这一点也不低效

例如,spring使用以下代码:

public static <A extends Annotation> A getAnnotation(
        Method method, Class<A> annotationType) {

    return BridgeMethodResolver.
       findBridgedMethod(method).getAnnotation(annotationType);
}
publicstaticagetannotation(
方法,类注释类型){
返回BridgeMethodResolver。
findBridgedMethod(method).getAnnotation(annotationType);
}
(其中,
BridgedMethodResolver
是另一个主题,但它只返回一个
方法
对象)


此外,与
null
相比,您可以使用
isAnnotationPresent(youranotation.class)
检查注释是否存在(如问题下方注释中所建议的)

如果要对每个类进行多次调用,则可以创建一个类似描述符的类,它只会缓存此类信息。然后,当您想要检索信息时,只需查看它的描述符

回答你的问题:

Class<?> _class = Whatever.class;
Annotation[] annos = _class.getAnnotations();
返回给定方法的所有注释。

查看(依赖项:和)。这是一个已经优化了大部分内容的库。有一个适合您的功能需求的

这里有一个,只是复制粘贴运行它

package com.stackoverflow;

import java.lang.reflect.Method;
import java.util.Set;

import org.reflections.Reflections;
import org.reflections.scanners.MethodAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;

public class Test {

    @Deprecated
    public static void main(String[] args) {
        Reflections reflections = new Reflections(new ConfigurationBuilder()
            .setUrls(ClasspathHelper.forPackage("com.stackoverflow"))
            .setScanners(new MethodAnnotationsScanner()));
        Set<Method> methods = reflections.getMethodsAnnotatedWith(Deprecated.class);
        System.out.println(methods);
    }

}
package com.stackoverflow;
导入java.lang.reflect.Method;
导入java.util.Set;
导入org.reflections.reflections;
导入org.reflections.scanners.MethodAnnotationsCanner;
导入org.reflections.util.ClasspathHelper;
导入org.reflections.util.ConfigurationBuilder;
公开课考试{
@不赞成
公共静态void main(字符串[]args){
反射反射=新反射(新配置生成器()
.setURL(ClasspathHelper.forPackage(“com.stackoverflow”))
.setScanners(新方法AnnotationsCanner());
Set methods=reflections.getMethodsAnnotatedWith(弃用的.class);
System.out.println(方法);
}
}

它类似于O(m*(1+a)),其中m=方法的数量,a=每个方法的平均注释数量。a通常接近于0,所以它实际上是O(m)。如果经常调用此代码,类似于O(log(m))的内容会更好。而且
m
很少超过10;)我不会把Spring作为效率的一个例子——有没有看过在Spring调用的方法中抛出异常时生成的堆栈跟踪?对于每个“真正”的方法调用,它必须经过六个级别的spring方法。幸运的是,java总体速度非常快,看起来不会造成问题,但在对spring在紧循环中实例化的对象调用方法之前,我会三思而后行……这不会只返回类级注释吗?方法类不会包括在内,他对它们感兴趣,它们已经缓存在
方法
对象中-它使用的是MapYes,但每次需要它们时都必须使用反射。我要说的是,一次访问该映射,永远不要再进行反射。如果您只想知道该方法是否有注释,而不关心注释的内容,则可以调用
method.isAnnotationPresent(HandlerMethod.class)
package com.stackoverflow;

import java.lang.reflect.Method;
import java.util.Set;

import org.reflections.Reflections;
import org.reflections.scanners.MethodAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;

public class Test {

    @Deprecated
    public static void main(String[] args) {
        Reflections reflections = new Reflections(new ConfigurationBuilder()
            .setUrls(ClasspathHelper.forPackage("com.stackoverflow"))
            .setScanners(new MethodAnnotationsScanner()));
        Set<Method> methods = reflections.getMethodsAnnotatedWith(Deprecated.class);
        System.out.println(methods);
    }

}