Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if method requires a parameter using annotation and reflect

Tags:

The question: Is there a way to do code inspection for a method and check if it doesn't have a parameter and warn me before compilation, or even give me a warning in my IDE.

Let's say I have an annotation @Initialize

@Retention(RetentionPolicy.RUNTIME)
public @interface Initialize {
    int priority();
}

And with reflect, I can invoke methods that are annotated with @Initialize

public static void initMethods(Initializable clazz) {
    TreeMap<Integer, Method> methods = prioritizedMethods(clazz.getClass().getDeclaredMethods());
    methods.forEach((priority, method) -> {
        try {
            method.setAccessible(true);
            Logger.debug("Invoking " + method.getName() + "...");
            method.invoke(clazz);
        } catch (IllegalAccessException | InvocationTargetException e) {
            Logger.debug("Failed to invoke " + method.getName());
            e.printStackTrace();
        }
    });
}

prioritzedMethods(Method[] method) is where I check for annotation.

private static TreeMap<Integer, Method> prioritizedMethods(Method[] methods) {
    HashMap<Integer, Method> taggedMethods = new HashMap<>();
    for (Method method : methods) {
        if (method.isAnnotationPresent(Initialize.class)) {
            Initialize meta = method.getAnnotation(Initialize.class);
            taggedMethods.put(meta.priority(), method);
        }
    }
    return new TreeMap<>(taggedMethods);
}

I want to make sure that all methods that are annotated with @Initialize do not have any parameter.

like image 709
Ethan Bacurio Avatar asked May 10 '18 20:05

Ethan Bacurio


People also ask

How do you check if a method has an annotation?

The isAnnotation() method is used to check whether a class object is an annotation. The isAnnotation() method has no parameters and returns a boolean value. If the return value is true , then the class object is an annotation. If the return value is false , then the class object is not an annotation.

How do you find the parameters of annotations?

getAnnotation(Annotation. class). param1() to get the param1 value. Here you have named your annotation interface as Annotation.

What is method Parameter reflection in java?

Overview. Method Parameter Reflection support was added in Java 8. Simply put, it provides support for getting the names of parameters at runtime. In this quick tutorial, we'll take a look at how to access parameter names for constructors and methods at runtime – using reflection.

What is the use of annotations in Java?

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.


1 Answers

I have written a framework for such common requirement. See deannotation-checker.

The only thing you should do is add @CheckMethod on your annotation.

@CheckMethod(argCount = 0, returnType = @CheckType(void.class))
public @interface Init {
   ...
}

Now your annotation has ability to restrict the annotated method. If you use it like

@Init
public void func(int i) {
  ...
}

You will get compile error

[5,15] Must only have 0 arguments.

If you IDE support (I'm using eclipse and m2e-apt plugin), you can get the error when save the file.

enter image description here

like image 72
Dean Xu Avatar answered Oct 02 '22 11:10

Dean Xu