Jak mogę sprawdzić, czy metoda jest statyczna za pomocą odbicia?

107

Chcę odkryć w czasie wykonywania TYLKO statyczne metody klasy, jak mogę to zrobić? Albo jak rozróżnić metody statyczne i niestatyczne.

Telcontar
źródło

Odpowiedzi:

182

Użyj Modifier.isStatic(method.getModifiers()).

/**
 * Returns the public static methods of a class or interface,
 *   including those declared in super classes and interfaces.
 */
public static List<Method> getStaticMethods(Class<?> clazz) {
    List<Method> methods = new ArrayList<Method>();
    for (Method method : clazz.getMethods()) {
        if (Modifier.isStatic(method.getModifiers())) {
            methods.add(method);
        }
    }
    return Collections.unmodifiableList(methods);
}

Uwaga: ta metoda jest w rzeczywistości niebezpieczna z punktu widzenia bezpieczeństwa. Class.getMethods „bypass [es] SecurityManager sprawdza w zależności od programu ładującego klasy bezpośrednio wywołującego” (patrz sekcja 6 wytycznych dotyczących bezpiecznego kodowania Java).

Zastrzeżenie: nie testowane ani nawet skompilowane.

Notatki Modifiernależy używać ostrożnie. Flagi reprezentowane jako ints nie są bezpieczne dla typów. Częstym błędem jest testowanie flagi modyfikatora na typie obiektu odbicia, do którego nie ma zastosowania. Może się zdarzyć, że flaga na tej samej pozycji jest ustawiona w celu wskazania innych informacji.

Tom Hawtin - haczyk
źródło
Edytuj odpowiedź: to Modifier zamiast ModifierS -> Użyj Modifier.isStatic (method.getModifiers ()) Dziękujemy za odpowiedź!
Telcontar
4
Tak, dzięki. Chociaż twierdzę, że nazwa jest błędnym projektem. Modyfikator nie reprezentuje modyfikatora. Ale potem cała klasa jest błędnym projektem. I prawdopodobnie także refleksja.
Tom Hawtin - tackline
btw to samo działa również dla Fields, które również udostępniają metodę getModifiers ()
Gregor
14

Możesz uzyskać metody statyczne w ten sposób:

for (Method m : MyClass.class.getMethods()) {
   if (Modifier.isStatic(m.getModifiers()))
      System.out.println("Static Method: " + m.getName());
}
bruno conde
źródło
5

Aby uściślić poprzednią (poprawną) odpowiedź, oto pełny fragment kodu, który robi to, co chcesz (wyjątki są ignorowane):

public Method[] getStatics(Class<?> c) {
    Method[] all = c.getDeclaredMethods()
    List<Method> back = new ArrayList<Method>();

    for (Method m : all) {
        if (Modifier.isStatic(m.getModifiers())) {
            back.add(m);
        }
    }

    return back.toArray(new Method[back.size()]);
}
Daniel Śpiewak
źródło