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

Исследование Модификаторов Класса и Типов

class может быть объявлен с одним или более модификаторами, которые влияют на его поведение времени выполнения:

Не все модификаторы позволяются на всех классах, например интерфейс не может быть final и перечисление не может быть abstract. java.lang.reflect.Modifier содержит объявления для всех возможных модификаторов. Это также содержит методы, которые могут использоваться, чтобы декодировать набор модификаторов, возвращенных Class.getModifiers().

ClassDeclarationSpy пример показывает, как получить компоненты объявления class включая модификаторы, универсальные параметры типа, реализованные интерфейсы, и путь наследования. С тех пор Class реализации java.lang.reflect.AnnotatedElement интерфейс также возможно запросить аннотации времени выполнения.


import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import static java.lang.System.out;

public class ClassDeclarationSpy {
    public static void main(String... args) {
	try {
	    Class<?> c = Class.forName(args[0]);
	    out.format("Class:%n  %s%n%n", c.getCanonicalName());
	    out.format("Modifiers:%n  %s%n%n",
		       Modifier.toString(c.getModifiers()));

	    out.format("Type Parameters:%n");
	    TypeVariable[] tv = c.getTypeParameters();
	    if (tv.length != 0) {
		out.format("  ");
		for (TypeVariable t : tv)
		    out.format("%s ", t.getName());
		out.format("%n%n");
	    } else {
		out.format("  -- No Type Parameters --%n%n");
	    }

	    out.format("Implemented Interfaces:%n");
	    Type[] intfs = c.getGenericInterfaces();
	    if (intfs.length != 0) {
		for (Type intf : intfs)
		    out.format("  %s%n", intf.toString());
		out.format("%n");
	    } else {
		out.format("  -- No Implemented Interfaces --%n%n");
	    }

	    out.format("Inheritance Path:%n");
	    List<Class> l = new ArrayList<Class>();
	    printAncestor(c, l);
	    if (l.size() != 0) {
		for (Class<?> cl : l)
		    out.format("  %s%n", cl.getCanonicalName());
		out.format("%n");
	    } else {
		out.format("  -- No Super Classes --%n%n");
	    }

	    out.format("Annotations:%n");
	    Annotation[] ann = c.getAnnotations();
	    if (ann.length != 0) {
		for (Annotation a : ann)
		    out.format("  %s%n", a.toString());
		out.format("%n");
	    } else {
		out.format("  -- No Annotations --%n%n");
	    }

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

    private static void printAncestor(Class<?> c, List<Class> l) {
	Class<?> ancestor = c.getSuperclass();
 	if (ancestor != null) {
	    l.add(ancestor);
	    printAncestor(ancestor, l);
 	}
    }
}

Несколько выборок вывода следуют. Ввод данных пользователем курсивом.

$ java ClassDeclarationSpy java.util.concurrent.ConcurrentNavigableMap
Class:
  java.util.concurrent.ConcurrentNavigableMap

Modifiers:
  public abstract interface

Type Parameters:
  K V

Implemented Interfaces:
  java.util.concurrent.ConcurrentMap<K, V>
  java.util.NavigableMap<K, V>

Inheritance Path:
  -- No Super Classes --

Annotations:
  -- No Annotations --

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

public interface ConcurrentNavigableMap<K,V>
    extends ConcurrentMap<K,V>, NavigableMap<K,V>
Отметьте, что, так как это - интерфейс, это неявно abstract. Компилятор добавляет этот модификатор для каждого интерфейса. Кроме того, это объявление содержит два универсальных параметра типа, K и V. Пример кода просто печатает имена этих параметров, но является этим возможный получить дополнительную информацию о них методы использования в java.lang.reflect.TypeVariable. Интерфейсы могут также реализовать другие интерфейсы как показано выше.
$ java ClassDeclarationSpy "[Ljava.lang.String;"
Class:
  java.lang.String[]

Modifiers:
  public abstract final

Type Parameters:
  -- No Type Parameters --

Implemented Interfaces:
  interface java.lang.Cloneable
  interface java.io.Serializable

Inheritance Path:
  java.lang.Object

Annotations:
  -- No Annotations --

Так как массивы являются объектами периода выполнения, вся информация о типе определяется виртуальной машиной Java. В частности выстраивает реализацию Cloneable и java.io.Serializable и их прямой суперкласс всегда Object.

$ java ClassDeclarationSpy java.io.InterruptedIOException
Class:
  java.io.InterruptedIOException

Modifiers:
  public

Type Parameters:
  -- No Type Parameters --

Implemented Interfaces:
  -- No Implemented Interfaces --

Inheritance Path:
  java.io.IOException
  java.lang.Exception
  java.lang.Throwable
  java.lang.Object

Annotations:
  -- No Annotations --

От пути наследования это может быть выведено это java.io.InterruptedIOException проверенное исключение потому что RuntimeException не присутствует.

$ java ClassDeclarationSpy java.security.Identity
Class:
  java.security.Identity

Modifiers:
  public abstract

Type Parameters:
  -- No Type Parameters --

Implemented Interfaces:
  interface java.security.Principal
  interface java.io.Serializable

Inheritance Path:
  java.lang.Object

Annotations:
  @java.lang.Deprecated()

Этот вывод показывает это java.security.Identity, осуждаемый API, обладает аннотацией java.lang.Deprecated. Это может использоваться отражающим кодом, чтобы обнаружить осуждаемые API.


Отметьте: Не все аннотации доступны через отражение. Только те, у которых есть a java.lang.annotation.RetentionPolicy из RUNTIME доступны. Из этих трех аннотаций, предопределенных на языке @Deprecated, @Override, и @SuppressWarnings только @Deprecated доступно во времени выполнения.

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

Предыдущая страница: Получение Объектов Класса
Следующая страница: Обнаружение Элементов Класса