-1

I am working on a project where I need to list all the methods of a certain class which have a certain property. So my problem is in two phases:

First I need to know how to give a method a certain property (I guess it's called metadata but I'm not sure at all).

Second, I need to get the names of all those methods with the given property.

PS: I know how to get the names of all the methods that a class has.

Here is a very abstract code to work with (there is nothing special with my original code that is crucial or even necessary to answer my question).

class App{
    public App(){}

    public void methodToSelect_1(){}

    public void method_NOT_toSelect(){}

    public void methodToSelect_2(){}
}

So it would be great if you could help me get as results a Method[] array containing methodToSelect_1() and methodToSelect_2() but not method_NOT_toSelect().

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Chihab
  • 403
  • 5
  • 11
  • *"I know how to get the names of all the methods that a class has."* Then what's the question? "How do I filter an array?" Surely you've found answers to that in your research / due diligence before posting? – T.J. Crowder Apr 19 '18 at 12:58
  • What's the criterion that specifies that the second should not be selected while the other 2 should be included? – Robert Kock Apr 19 '18 at 12:59
  • @RobertKock, that's to be fixed by answering the first part of my question, how to give certain methods properties to distinguish them from other methods? – Chihab Apr 19 '18 at 13:08
  • 2
    It looks like you might want to use custom Java annotations? https://en.wikipedia.org/wiki/Java_annotation – SirDarius Apr 19 '18 at 13:08
  • @T.J.Crowder, Yes, that'd be the second part of my question. – Chihab Apr 19 '18 at 13:09
  • 1
    Have a look at this: https://stackoverflow.com/questions/1805200/retrieve-java-annotation-attribute – Robert Kock Apr 19 '18 at 13:55

2 Answers2

0

I did some same work recently. In fact, there is no obvious way to do that, you have to found your own solution. In my case, I wanted to get the getters, so I did something like that :

    Method[] m = someObjectHavingMethods.getClass().getDeclaredMethods();

    // Loop over number of methods
    for (int i=0;i<m.length;i++) {

        // If methods contain "get" (case non-sensitive)
        if (Pattern.compile(Pattern.quote("get"), Pattern.CASE_INSENSITIVE).matcher(m[i].toString()).find()) {

            // If methods contain "someExpectedPattern" (case non-sensitive)
            if (Pattern.compile(Pattern.quote("someExpectedPattern"), Pattern.CASE_INSENSITIVE).matcher(m[i].toString()).find()) {
                try {
                    System.out.println(m[i].invoke(someObjectHavingMethods));
                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }

So basically you need to loop on all Methods, and then find a way to select Methods you know something about, like "get" for getters.

Lutzi
  • 416
  • 2
  • 13
-1

I have, thanks to @Robert Knock's indication, found a solution to my problem. I am posting my answer for future reference.

So Say we have the following package annots_package and the following annotation:

package annots_package;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface ToSelect {

    boolean selectable();

}

With the following class that has the method to select other methods: package annots_package;

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

public class Main {

    public static ArrayList<Method> selectedMethods = new ArrayList<Method>();

    public Main() {
        System.out.println("Instanciated Main");
    }

    @ToSelect(selectable = false)
    public static void main(String[] args) throws Exception {
        Class<?> c = Class.forName("annots_package.Main");
        Method[] methods = c.getDeclaredMethods();
        for(Method method : methods) {
            ToSelect annotation = method.getAnnotation(ToSelect.class);
            if(annotation != null) {
                boolean selectable = annotation.selectable();
                if (selectable) {
                    selectedMethods.add(method);
                }
            }
        }

        for(Method method : selectedMethods) {
            System.out.println(method.toString());
        }

    }

    @ToSelect(selectable = true)
    public void method_1() {
        System.out.println("method_1");
    }

    @ToSelect(selectable = false)
    public void method_2() {
        System.out.println("method_2");
    }

    @ToSelect(selectable = true)
    public void method_3() {
        System.out.println("method_3");
    }

}

So in order for me to select only method_1() and method_3() which are annotated @ToSelect(selectable = true), I first made a list of all the methods the class has, then created an annotation for each method, next, I checked if annotation is not null (since the method main() has no annotation, it could throw a NullPointerException) so this way, I avoided that. And only then I checked if the selectable() attribute of the annotation is true (could be something else). This way I made my ArrayList of methods I am interested in.

Thanks everyone.

Chihab
  • 403
  • 5
  • 11