След: API Reflection
Урок: Элементы
Раздел: Конструкторы
Обнаружение Конструкторов
Домашняя страница > API Reflection > Элементы

Обнаружение Конструкторов

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

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


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

public class ConstructorSift {
    public static void main(String... args) {
	try {
	    Class<?> cArg = Class.forName(args[1]);

	    Class<?> c = Class.forName(args[0]);
	    Constructor[] allConstructors = c.getDeclaredConstructors();
	    for (Constructor ctor : allConstructors) {
		Class<?>[] pType  = ctor.getParameterTypes();
		for (int i = 0; i < pType.length; i++) {
		    if (pType[i].equals(cArg)) {
			out.format("%s%n", ctor.toGenericString());

			Type[] gpType = ctor.getGenericParameterTypes();
			for (int j = 0; j < gpType.length; j++) {
			    char ch = (pType[j].equals(cArg) ? '*' : ' ');
			    out.format("%7c%s[%d]: %s%n", ch,
				       "GenericParameterType", j, gpType[j]);
			}
			break;
		    }
		}
	    }

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

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

Вот вывод для всех конструкторов в java.util.Formatter у которых есть a Locale параметр.

$ java ConstructorSift java.util.Formatter java.util.Locale
public
java.util.Formatter(java.io.OutputStream,java.lang.String,java.util.Locale)
throws java.io.UnsupportedEncodingException
       GenericParameterType[0]: class java.io.OutputStream
       GenericParameterType[1]: class java.lang.String
      *GenericParameterType[2]: class java.util.Locale
public java.util.Formatter(java.lang.String,java.lang.String,java.util.Locale)
throws java.io.FileNotFoundException,java.io.UnsupportedEncodingException
       GenericParameterType[0]: class java.lang.String
       GenericParameterType[1]: class java.lang.String
      *GenericParameterType[2]: class java.util.Locale
public java.util.Formatter(java.lang.Appendable,java.util.Locale)
       GenericParameterType[0]: interface java.lang.Appendable
      *GenericParameterType[1]: class java.util.Locale
public java.util.Formatter(java.util.Locale)
      *GenericParameterType[0]: class java.util.Locale
public java.util.Formatter(java.io.File,java.lang.String,java.util.Locale)
throws java.io.FileNotFoundException,java.io.UnsupportedEncodingException
       GenericParameterType[0]: class java.io.File
       GenericParameterType[1]: class java.lang.String
      *GenericParameterType[2]: class java.util.Locale

Следующий вывод в качестве примера иллюстрирует, как искать параметр типа char[] в String.

$ java ConstructorSift java.lang.String "[C"
java.lang.String(int,int,char[])
       GenericParameterType[0]: int
       GenericParameterType[1]: int
      *GenericParameterType[2]: class [C
public java.lang.String(char[],int,int)
      *GenericParameterType[0]: class [C
       GenericParameterType[1]: int
       GenericParameterType[2]: int
public java.lang.String(char[])
      *GenericParameterType[0]: class [C

Синтаксис для того, чтобы выразить массивы ссылочных типов и типов примитивов, приемлемых для Class.forName() описывается в Class.getName(). Отметьте, что первый перечисленный конструктор package-private, нет public. Это возвращается, потому что пример кода использует Class.getDeclaredConstructors() вместо Class.getConstructors(), который возвращается только public конструкторы.

Этот пример показывает, что поиск параметров переменной арности (у которых есть переменное число параметров) требует использования синтаксиса массива:

$ java ConstructorSift java.lang.ProcessBuilder "[Ljava.lang.String;"
public java.lang.ProcessBuilder(java.lang.String[])
      *GenericParameterType[0]: class [Ljava.lang.String;

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

public ProcessBuilder(String... command)

Параметр представляется как массив единственной размерности типа java.lang.String. Это можно отличить от параметра, который является явно массивом java.lang.String вызывая Constructor.isVarArgs().

Заключительный пример сообщает о выводе для конструктора, который был объявлен с универсальным типом параметра:

$ java ConstructorSift java.util.HashMap java.util.Map
public java.util.HashMap(java.util.Map<? extends K, ? extends V>)
      *GenericParameterType[0]: java.util.Map<? extends K, ? extends V>

Типы исключения могут быть получены для конструкторов похожим способом что касается методов. См. MethodSpy пример, описанный в Получении раздела информации о Типе Метода для получения дальнейшей информации.


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

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



Spec-Zone.ru - all specs in one place