Методы и класс Method

Последнее обновление: 29.09.2025

Класс java.lang.reflect.Method предоставляет информацию об одном методе класса или интерфейса и доступ к нему. Для получения информации о методах и управления ими класс Method определеяет ряд методов. Отмечу основные из них:

  • String getName(): возвращает имя метода

  • Class[] getExceptionTypes(): возвращает генерируемые методом типы исключений в виде массива объектов Class

  • int getModifiers(): возвращает целое число с различными включенными и выключенными битами, которые описывают используемые модификаторы.

  • int getParameterCount(): возвращает количество параметров

  • Class[] getParameterTypes(): возвращает типы параметров метода

  • Class getReturnType(): возвращает тип возвращаемого значения метода

  • Object invoke(Object obj, Object... args): вызывает метод, представленный этим объектом метода, для указанного объекта с указанными параметрами.

Получение методов

Для получения методов типа применяется ряд методов класса Class:

  • Method[] getMethods(): возвращает массив объектов Method для открытых методов (с модификатором public) данного класса или его суперклассов

  • Method[] getDeclaredКласс java.lang.reflect.Methods(): возвращает массив объектов Method для всех методов данного класса. Метод возвращают массив нулевой длины, если таких методов нет или если объект представляет собой примитивный тип или массив.

  • Method getMethod(String name, Class... parameterTypes): возвращает объект Method для публичного метода, имя которого передается в качестве параметра. Второй параметр указывает на типы параметров метода. Поиск также идет среди методов суперклассов. Если подобное публичный метод отсутствует, то метод генерирует исключение NoSuchMethodException

  • Method getDeclaredMethod(String name, Class... parameterTypes): возвращает объект Method для метода, имя которого передается в качестве параметра. Второй параметр указывает на типы параметров метода. Если подобный метод отсутствует, то метод генерирует исключение NoSuchMethodException

Например, получим все методы некоторого класса:

import java.lang.reflect.*;

public class Program{
      
    public static void main(String[] args) {
        
        Class cl = Operation.class;
        Method[] methods = cl.getDeclaredMethods();
        for(Method m : methods){
            System.out.println(m);
        }
    }
}

class Operation{

    static int sum(int val1, int val2){
        return val1 + val2;
    }

    static double sum(double val1, double val2){
        return val1 + val2;
    }

    static int subtract(int val1, int val2){
        return val1 - val2;
    }
}

В данном случае получаем методы класса Operation. И консоль должна нам вывести следующие строки:

static int Operation.sum(int,int)
static double Operation.sum(double, double)
static int Operation.subtract(int,int)

Исследование метода

Исследуем метод sum из выше определенного класса Operation:

import java.lang.reflect.*;

public class Program{
      
    public static void main(String[] args) {
        
        Class cl = Operation.class;
        try{
            // получаем метод sum с двумя параметрами типа int
            Method m = cl.getDeclaredMethod("sum", int.class, int.class);
            // получаем имя метода
            String methodName = m.getName();
            // получаем модификаторы
            String modifiers = Modifier.toString(m.getModifiers());

            // получаем количество параметров
            int paramsCount = m.getParameterCount();
            // получаем возвращаемый тип
            Class retType = m.getReturnType();
            // получаем типы параметров
            Class[] paramTypes = m.getParameterTypes();

            // выводим информацию о методе
            System.out.print(modifiers + " " + retType.getName() + " " + methodName + "(");
            for (int j = 0; j < paramsCount; j++)
            {
                if (j > 0) System.out.print(", ");
                System.out.print(paramTypes[j].getName());
            }
            System.out.println(");");
        }
        catch(Exception ex){

            System.out.println(ex);
        }
    }
}

class Operation{

    static int sum(int val1, int val2){
        return val1 + val2;
    }

    static double sum(double val1, double val2){
        return val1 + val2;
    }

    static int subtract(int val1, int val2){
        return val1 - val2;
    }
}

В данном случае получаем метод sum, который принимает два параметра типа int:

Method m = cl.getDeclaredMethod("sum", int.class, int.class);

Далее последовательно получаем имя, возвращаемый тип, модификаторы и типы параметров метода и выводим их на консоль. В итоге консоль должна нам вывести следующую строку:

static int sum(int, int);

Вызов метода

Для вызова метода в классе Method определен метод invoke():

public Object invoke(Object obj, Object... args)
              throws IllegalAccessException, InvocationTargetException

Первый параметр (obj) представляет объект, для которого будет вызываться метод. Если вызываемый метод статический, то параметр obj игнорируется.

Второй параметр (args) представляет аргументы, передаваемые вызываемому методу. Если вызываемый метод не принимает никаких параметров, то параметр args опускается.

Возвращаемое значение - это результат вызываемого метода.

Вызов статического метода

Вызовем статический метод sum класса Operation:

import java.lang.reflect.*;

public class Program{
      
    public static void main(String[] args) {
        
        Class cl = Operation.class;
        try{
            // получаем метод sum с двумя параметрами типа int
            Method m = cl.getDeclaredMethod("sum", int.class, int.class);
            int val1 = 23;
            int val2 = 4;
            // вызываем метод и получаем результат
            int result = (int) m.invoke(null, val1, val2);

            System.out.printf("sum(%d, %d) = %d\n", val1, val2, result);        // sum(23, 4) = 27
        }       
        catch(Exception ex){

            System.out.println(ex);
        }
    }
}

class Operation{

    static int sum(int val1, int val2){
        return val1 + val2;
    }

    static int subtract(int val1, int val2){
        return val1 - val2;
    }
}

Поскольку вызываемый метод sum - статический, то в качестве первого параметра передается null:

int result = (int) m.invoke(null, val1, val2);

Результаи преобразуется к типу int, так как мы значем, что метод должен возвратить значение этого типа. Консольный вывод программы:

sum(23, 4) = 27

Вызов нестатического метода

Рассмотрим вызов нестатического метода:

import java.lang.reflect.*;

public class Program{
      
    public static void main(String[] args) {
        
        // объект, для которого будет вызываться метод
        Person tom = new Person("Tom");
        Class cl = tom.getClass();
        try{
            // получаем метод setName с параметром типа String
            Method m = cl.getDeclaredMethod("setName", String.class);
            // новое имя
            String name = "Eugene";
            // вызываем метод
            m.invoke(tom, name);

            tom.print();        // Person Eugene
        }       
        catch(Exception ex){

            System.out.println(ex);
        }
    }
}
class Person {
     
    private String name;

    void setName(String name){ this.name = name; }

    Person(String name){  this.name = name; }
    
    void print(){
        System.out.println("Person " + name);
    }
} 

В данном случае для объекта Person вызываем метод setName(), который изменяет значение поля name.

Приватные методы

Как и в случае с полями и конструкторами, механизм рефлексии Java запрещает обращение к приватным методам (определенным с модификатором private). В этом случае для доступа к методу необходимо сделать его доступным с помощью метода setAccessible(), передав в него true:

import java.lang.reflect.*;

public class Program{
      
    public static void main(String[] args) {
        
        Person tom = new Person("Tom");
        Class cl = tom.getClass();

        try{
            Method m = cl.getDeclaredMethod("setName", String.class);
            m.setAccessible(true);      // открываем доступ к методу

            String name = "Eugene";

            m.invoke(tom, name);

            tom.print();        // Person Eugene
        }       
        catch(Exception ex){

            System.out.println(ex);
        }
    }
}
class Person {
     
    private String name;
    // приватный метод
    private void setName(String name){ this.name = name; }

    Person(String name){  this.name = name; }
    
    void print(){
        System.out.println("Person " + name);
    }
} 
Помощь сайту
Юмани:
410011174743222
Номер карты:
4048415020898850