Bagaimana cara memeriksa apakah suatu metode statis menggunakan refleksi?

107

Saya ingin menemukan pada run-time HANYA Metode statis kelas, bagaimana saya bisa melakukan ini? Atau, bagaimana membedakan antara metode statis dan non-statis.

Telcontar
sumber

Jawaban:

182

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

Catatan: Metode ini sebenarnya berbahaya dari sudut pandang keamanan. Class.getMethods "bypass [es] Pemeriksaan SecurityManager bergantung pada pemuat kelas pemanggil langsung" (lihat bagian 6 dari pedoman pengodean aman Java).

Penafian: Tidak diuji atau bahkan dikompilasi.

Catatan Modifierharus digunakan dengan hati-hati. Bendera yang direpresentasikan sebagai int bukanlah tipe aman. Kesalahan umum adalah menguji bendera pengubah pada tipe objek refleksi yang tidak diterapkan padanya. Ini mungkin kasus bahwa bendera di posisi yang sama diatur untuk menunjukkan beberapa informasi lain.

Tom Hawtin - tackline
sumber
Edit jawabannya: adalah Modifier dan bukan ModifierS -> Gunakan Modifier.isStatic (method.getModifiers ()) Thx for the Answer!
Telcontar
4
Yup, terima kasih. Meskipun saya mengklaim nama itu salah desain. Pengubah tidak mewakili pengubah. Tapi kemudian seluruh kelas adalah desain yang salah. Dan mungkin juga refleksi.
Tom Hawtin - tackline
btw yang sama juga berfungsi untuk Fields, yang juga menyediakan metode getModifiers ()
Gregor
14

Anda bisa mendapatkan metode statis seperti ini:

for (Method m : MyClass.class.getMethods()) {
   if (Modifier.isStatic(m.getModifiers()))
      System.out.println("Static Method: " + m.getName());
}
bruno conde
sumber
5

Untuk menyempurnakan jawaban sebelumnya (benar), berikut ini cuplikan kode lengkap yang melakukan apa yang Anda inginkan (pengecualian diabaikan):

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 Spiewak
sumber