Spec-Zone .ru
спецификации, руководства, описания, API
След: API Reflection
Урок: Элементы
Раздел: Методы
Получение информации о Типе Метода
Домашняя страница > API Reflection > Элементы

Получение информации о Типе Метода

Объявление метода включает имя, модификаторы, параметры, возвращают тип, и список throwable исключений. java.lang.reflect.Method class обеспечивает способ получить эту информацию.

MethodSpy пример иллюстрирует, как перечислить все объявленные методы в данном class и получить возврат, параметр, и типы исключения для всех методов имени.


import java.lang.reflect.Method;
import java.lang.reflect.Type;
import static java.lang.System.out;

public class MethodSpy {
    private static final String  fmt = "%24s: %s%n";

    // for the morbidly curious
    <E extends RuntimeException> void genericThrow() throws E {}

    public static void main(String... args) {
	try {
	    Class<?> c = Class.forName(args[0]);
	    Method[] allMethods = c.getDeclaredMethods();
	    for (Method m : allMethods) {
		if (!m.getName().equals(args[1])) {
		    continue;
		}
		out.format("%s%n", m.toGenericString());

		out.format(fmt, "ReturnType", m.getReturnType());
		out.format(fmt, "GenericReturnType", m.getGenericReturnType());

		Class<?>[] pType  = m.getParameterTypes();
		Type[] gpType = m.getGenericParameterTypes();
		for (int i = 0; i < pType.length; i++) {
		    out.format(fmt,"ParameterType", pType[i]);
		    out.format(fmt,"GenericParameterType", gpType[i]);
		}

		Class<?>[] xType  = m.getExceptionTypes();
		Type[] gxType = m.getGenericExceptionTypes();
		for (int i = 0; i < xType.length; i++) {
		    out.format(fmt,"ExceptionType", xType[i]);
		    out.format(fmt,"GenericExceptionType", gxType[i]);
		}
	    }

        // production code should handle these exceptions more gracefully
	} catch (ClassNotFoundException x) {
	    x.printStackTrace();
	}
    }
}

Вот вывод для Class.getConstructor() который является примером метода с параметризованными типами и переменным числом параметров.

$ java MethodSpy java.lang.Class getConstructor
public java.lang.reflect.Constructor<T> java.lang.Class.getConstructor
  (java.lang.Class<?>[]) throws java.lang.NoSuchMethodException,
  java.lang.SecurityException
              ReturnType: class java.lang.reflect.Constructor
       GenericReturnType: java.lang.reflect.Constructor<T>
           ParameterType: class [Ljava.lang.Class;
    GenericParameterType: java.lang.Class<?>[]
           ExceptionType: class java.lang.NoSuchMethodException
    GenericExceptionType: class java.lang.NoSuchMethodException
           ExceptionType: class java.lang.SecurityException
    GenericExceptionType: class java.lang.SecurityException

Это - фактическое объявление метода в исходном коде:

public Constructor<T> getConstructor(Class<?>... parameterTypes)

Сначала отметьте, что возврат и типы параметра универсальны. Method.getGenericReturnType() будет консультироваться с Атрибутом Подписи в файле class, если это будет присутствовать. Если атрибут не доступен, он возвращается Method.getReturnType() который не был изменен введением обобщений. Другие методы с именем getGenericFoo() поскольку некоторое значение Foo в отражении реализуется так же.

Затем, заметьте что последнее (и только) параметр, parameterType, имеет переменную арность (имеет переменное число параметров) типа java.lang.Class. Это представляется как массив единственной размерности типа java.lang.Class. Это можно отличить от параметра, который является явно массивом java.lang.Class вызывая Method.isVarArgs(). Синтаксис для возвращенных значений Method.get*Types() описывается в Class.getName().

Следующий пример иллюстрирует метод с универсальным типом возврата.

$ java MethodSpy java.lang.Class cast
public T java.lang.Class.cast(java.lang.Object)
              ReturnType: class java.lang.Object
       GenericReturnType: T
           ParameterType: class java.lang.Object
    GenericParameterType: class java.lang.Object

Универсальный возврат вводит для метода Class.cast() сообщается как java.lang.Object потому что обобщения реализуются через стирание типа, которое удаляет всю информацию относительно универсальных типов во время компиляции. Стирание T определяется объявлением Class:

public final class Class<T> implements ...

Таким образом T заменяется верхней границей переменной типа, в этом случае, java.lang.Object.

Последний пример иллюстрирует вывод для метода с многократными перегрузками.

$ java MethodSpy java.io.PrintStream format
public java.io.PrintStream java.io.PrintStream.format
  (java.util.Locale,java.lang.String,java.lang.Object[])
              ReturnType: class java.io.PrintStream
       GenericReturnType: class java.io.PrintStream
           ParameterType: class java.util.Locale
    GenericParameterType: class java.util.Locale
           ParameterType: class java.lang.String
    GenericParameterType: class java.lang.String
           ParameterType: class [Ljava.lang.Object;
    GenericParameterType: class [Ljava.lang.Object;
public java.io.PrintStream java.io.PrintStream.format
  (java.lang.String,java.lang.Object[])
              ReturnType: class java.io.PrintStream
       GenericReturnType: class java.io.PrintStream
           ParameterType: class java.lang.String
    GenericParameterType: class java.lang.String
           ParameterType: class [Ljava.lang.Object;
    GenericParameterType: class [Ljava.lang.Object;

Если многократные перегрузки того же самого имени метода обнаруживаются, они все возвращаются Class.getDeclaredMethods(). С тех пор format() имеет две перегрузки (с с a Locale и один без), обоими показывают MethodSpy.


Отметьте: Method.getGenericExceptionTypes() существует, потому что фактически возможно объявить метод с универсальным типом исключения. Однако это редко используется, так как не возможно поймать универсальный тип исключения.

Проблемы с примерами? Попытайтесь Компилировать и Выполнить Примеры: FAQ.
Жалобы? Поздравление? Предложения? Дайте нам свою обратную связь.

Предыдущая страница: Методы
Следующая страница: Получение и Парсинг Модификаторов Метода