Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a more efficient way to get an annotated method?

I started a "for fun, nobody knows, nobody cares" open source project (LinkSet).

In one place I need to get an annotated method of a class.

Is there a more efficient way to do it than this? I mean without the need of iterating through every method?

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

    final HandlerMethod handler = method.getAnnotation(HandlerMethod.class);
        if (handler != null) {
                return method;
          }
        }
like image 503
Łukasz Bownik Avatar asked Feb 10 '10 14:02

Łukasz Bownik


People also ask

What is annotated method?

Annotations are used to provide supplemental information about a program. Annotations start with '@'. Annotations do not change the action of a compiled program. Annotations help to associate metadata (information) to the program elements i.e. instance variables, constructors, methods, classes, etc.

What is the benefit of using annotation?

Why Annotate? By annotating a text, you will ensure that you understand what is happening in a text after you've read it. As you annotate, you should note the author's main points, shifts in the message or perspective of the text, key areas of focus, and your own thoughts as you read.

What are the advantages of annotations in Java?

The benefits of type annotations and example use cases For instance, they can produce informational messages for the developer at compile time, detecting errors or suppressing warnings. In addition, annotations can be processed to generate Java source files or resources that can be used to modify annotated code.


2 Answers

Take a look for Reflections (dependencies: Guava and Javassist). It's a library which has already optimized the most of it all. There's a Reflections#getMethodsAnnotatedWith() which suits your functional requirement.

Here's an SSCCE, just copy'n'paste'n'run it.

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);
    }

}
like image 168
BalusC Avatar answered Sep 22 '22 12:09

BalusC


If you're going to make several calls to this for every class you can create a descriptor like class which does nothing more than cache this type of information. Then when you want to retrieve the information you just look at it's descriptor.

To answer your question:

Class<?> _class = Whatever.class;
Annotation[] annos = _class.getAnnotations();

will return all annotations of a class. What you've done will only return the very first annotation of a method. Like wise:

Annotion[] annos = myMethod.getAnnotations();

returns all the annotations of a given method.

like image 36
wheaties Avatar answered Sep 23 '22 12:09

wheaties