Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Получение информации о методах класса через Reflection
Задача получить список всех методов (или режимов) класса критична для фреймворков, инструментов инспекции и тестирования.
1. Получение массива методов
Базовый способ получить все методы класса:
Class<?> clazz = String.class;
// Все методы класса, включая приватные
Method[] allMethods = clazz.getDeclaredMethods();
// Только публичные методы (включая наследованные)
Method[] publicMethods = clazz.getMethods();
System.out.println("Total declared methods: " + allMethods.length);
for (Method m : allMethods) {
System.out.println(m.getName());
}
2. Фильтрация методов в список
Соберите методы в коллекцию с условиями:
// Собрать все getter методы
List<Method> getters = Arrays.stream(clazz.getDeclaredMethods())
.filter(m -> m.getName().startsWith("get"))
.collect(Collectors.toList());
// Все public нестатические методы
List<Method> instanceMethods = Arrays.stream(clazz.getDeclaredMethods())
.filter(m -> !Modifier.isStatic(m.getModifiers()))
.filter(m -> Modifier.isPublic(m.getModifiers()))
.collect(Collectors.toList());
// Методы, возвращающие void
List<Method> voidMethods = Arrays.stream(clazz.getDeclaredMethods())
.filter(m -> m.getReturnType() == void.class)
.collect(Collectors.toList());
3. Получение режимов (модификаторов) метода
Method method = String.class.getMethod("length");
// Получить bitset модификаторов
int modifiers = method.getModifiers();
// Проверить конкретные режимы
boolean isPublic = Modifier.isPublic(modifiers);
boolean isStatic = Modifier.isStatic(modifiers);
boolean isFinal = Modifier.isFinal(modifiers);
boolean isSynchronized = Modifier.isSynchronized(modifiers);
boolean isNative = Modifier.isNative(modifiers);
boolean isAbstract = Modifier.isAbstract(modifiers);
// Вывести читаемую строку модификаторов
String modifierString = Modifier.toString(modifiers);
System.out.println(modifierString); // public final
4. Полная информация о методе
public void printMethodInfo(Method method) {
System.out.println("==== Method: " + method.getName() + " ===");
// Возвращаемый тип
Class<?> returnType = method.getReturnType();
System.out.println("Return type: " + returnType.getSimpleName());
// Параметры
Class<?>[] parameterTypes = method.getParameterTypes();
String params = Arrays.stream(parameterTypes)
.map(Class::getSimpleName)
.collect(Collectors.joining(", "));
System.out.println("Parameters: (" + params + ")");
// Модификаторы
int modifiers = method.getModifiers();
System.out.println("Modifiers: " + Modifier.toString(modifiers));
// Выброшенные исключения
Class<?>[] exceptionTypes = method.getExceptionTypes();
if (exceptionTypes.length > 0) {
String exceptions = Arrays.stream(exceptionTypes)
.map(Class::getSimpleName)
.collect(Collectors.joining(", "));
System.out.println("Throws: " + exceptions);
}
// Класс, который объявил метод
System.out.println("Declared in: " + method.getDeclaringClass().getName());
}
5. Получение параметров метода
Method method = clazz.getDeclaredMethod("substring", int.class, int.class);
Parameter[] parameters = method.getParameters();
for (Parameter param : parameters) {
System.out.println("Parameter: " + param.getName());
System.out.println("Type: " + param.getType().getSimpleName());
System.out.println("Index: " + param.getParameterizedType());
}
6. Методы с аннотациями
// Получить все аннотации метода
Method method = clazz.getDeclaredMethod("equals", Object.class);
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println("Annotation: " + annotation.annotationType().getSimpleName());
}
// Проверить наличие конкретной аннотации
if (method.isAnnotationPresent(Override.class)) {
System.out.println("Method overrides parent method");
}
7. Вызов метода через reflection
public Object invokeMethod(Object target, String methodName, Object... args)
throws Exception {
Class<?>[] paramTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
paramTypes[i] = args[i].getClass();
}
Method method = target.getClass().getDeclaredMethod(methodName, paramTypes);
method.setAccessible(true);
return method.invoke(target, args);
}
8. Полный пример: инспектор класса
public class ClassInspector {
public static void inspect(Class<?> clazz) {
System.out.println("\n=== Inspecting class: " + clazz.getName() + " ===");
Method[] methods = clazz.getDeclaredMethods();
System.out.println("Total methods: " + methods.length);
Map<String, List<Method>> byModifiers = new HashMap<>();
for (Method method : methods) {
String mods = Modifier.toString(method.getModifiers());
byModifiers.computeIfAbsent(mods, k -> new ArrayList<>()).add(method);
}
// Вывести методы, сгруппированные по модификаторам
byModifiers.forEach((mods, methodList) -> {
System.out.println("\n[" + mods + "]");
methodList.forEach(m -> {
String signature = m.getReturnType().getSimpleName() + " " + m.getName() + "()";
System.out.println(" " + signature);
});
});
}
}
// Использование
ClassInspector.inspect(ArrayList.class);
9. Оптимизация: кэширование методов
public class MethodCache {
private static final Map<Class<?>, Map<String, Method>> cache =
new ConcurrentHashMap<>();
public static Method getMethod(Class<?> clazz, String methodName) {
return cache
.computeIfAbsent(clazz, k -> {
Map<String, Method> methods = new HashMap<>();
for (Method m : k.getDeclaredMethods()) {
methods.put(m.getName(), m);
}
return methods;
})
.get(methodName);
}
}
Важные замечания
getDeclaredMethods()— все методы класса, включая приватныеgetMethods()— только публичные, из класса и родителей- Рефлексия медленнее в 10-100 раз — кэшируйте результаты
setAccessible(true)нужна для доступа к приватным методам
Этот подход критичен для фреймворков, DI контейнеров и инструментов инспекции кода.