← Назад к вопросам

Как собрать лист с режимами класса

2.2 Middle🔥 181 комментариев
#Другое

Комментарии (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 контейнеров и инструментов инспекции кода.

Как собрать лист с режимами класса | PrepBro