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

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

Для исследования типов в программе кроме класса Class язык Java предоставляет еще ряд классов, которые определены главным образом в пакете java.lang.reflect:

  • Field: описывает поле класса

  • Method: описывает метод типа

  • Constructor: описывает конструктор класса

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

  • Field[] getFields() / getDeclaredFields(): возвращает поля класса

  • Method[] getMethods() / getDeclaredMethods(): возвращает методы класса

  • Constructor[] getConstructors() / getDeclaredConstructors(): возвращает конструкторы класса

Методы getFields(), getMethods() и getConstructors() возвращают массивы общедоступных полей, методов и конструкторов (определенных с модификатором public), поддерживаемых классом, в том числе и поля и методы, унаследованные от суперклассов. Методы getDeclaredFields(), getDeclaredMethods() и getDeclaredConstructors() возвращают массивы из всех полей, методов и конструкторов, объявленных непосредственно в классе, в том числе и закрытые, приватные компоненты. Но эти массивы НЕ включают компоненты суперклассов.

Таким образом, в зависимости от уровня доступа компонентов а также от того, хотим мы получить также компоненты суперклассов или хотим ограничиться компонентами, которые определены непосредственно в классе, зависит выбор конкретного метода для получения компонентов.

Допустим, у нас есть следующая иерархия классов:


class Person {
     
    private String name;
    private int age;

    public String getName() {return name;}
    public int getAge() {return age;}

    public Person(){
        this.name = "Undefined";
        this.age = 18;
    }
    public Person(String name, int age){ 

        this.name = name;
        this.age = age;
    }
 
}

Исследуем тип Person:

import java.lang.reflect.*;

public class Program{
      
    public static void main(String[] args) {
        
        // получаем класс для класса Person
        Class personClass = Person.class;

        Field[] fields = personClass.getFields();
        Method[] methods = personClass.getMethods();
        Constructor[] ctors = personClass.getConstructors();

        System.out.println("Public Fields");
        for(Field field : fields){
            System.out.println(field);
        }
        System.out.println("\nPublic Ctors");
        for(Constructor ctor : ctors){
            System.out.println(ctor);
        }

        System.out.println("\nPublic Methods");
        for(Method method : methods){
            System.out.println(method);
        }
    }
}

В данном случае используем методы getFields(), getMethods() и getConstructors() для получения всех публичных компонентов класса, в том числе унаследованных от класса Person. Консольный вывод программы:

Public Fields

Public Ctors
public Person(java.lang.String,int)
public Person()

Public Methods
public java.lang.String Person.getName()
public int Person.getAge()
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
public final void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException

Преимуществом классов Field/Method/Constructor является то, что в Java уже по умолчанию реализован полноценный вывод компонента, что очень удобно при выводе на консоль. И в данном случае мы видим, что методы вывели только публичные компоненты, в том числе и унаследованные от класса Object.

Теперь применим другой набор методов для получения информации о классе - getDeclaredFields()/getDeclaredMethods()/getDeclaredConstructors():

import java.lang.reflect.*;

public class Program{
      
    public static void main(String[] args) {
        
        // получаем класс для класса Person
        Class personClass = Person.class;

        Field[] fields = personClass.getDeclaredFields();
        Method[] methods = personClass.getDeclaredMethods();
        Constructor[] ctors = personClass.getDeclaredConstructors();

        System.out.println("Fields");
        for(Field field : fields){
            System.out.println(field);
        }
        System.out.println("\nCtors");
        for(Constructor ctor : ctors){
            System.out.println(ctor);
        }

        System.out.println("\nMethods");
        for(Method method : methods){
            System.out.println(method);
        }
    }
}

Консольный вывод:

Fields
private java.lang.String Person.name
private int Person.age

Ctors
public Person(java.lang.String,int)
public Person()

Methods
public java.lang.String Person.getName()
public int Person.getAge()

Подобным образом мы можем исследовать и встроенные типы данных. Например, исследуем тип String (ограничимся конструкторами):

import java.lang.reflect.*;

public class Program{
      
    public static void main(String[] args) {
        
        Class strClass = String.class;

        Constructor[] ctors = strClass.getConstructors();

        for(Constructor ctor : ctors){
            System.out.println(ctor);
        }
    }
}

Консольный вывод:

public java.lang.String(java.lang.StringBuilder)
public java.lang.String(byte[],int,int,java.nio.charset.Charset)
public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],java.nio.charset.Charset)
public java.lang.String(byte[],int,int)
public java.lang.String(byte[])
public java.lang.String(java.lang.StringBuffer)
public java.lang.String(char[],int,int)
public java.lang.String(char[])
public java.lang.String(java.lang.String)
public java.lang.String()
public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int)
public java.lang.String(byte[],int,int,int)
public java.lang.String(int[],int,int)

Проверка типа

Ряд методов класса Class позволяют проверить исследуемый тип:

  • boolean isAnonymousClass(): возвращает true, если тип является анонимным классом

  • boolean isArray(): возвращает true, если тип представляет массив

  • boolean isPrimitive(): возвращает true, если тип является примитивным типом

  • boolean isInterface(): возвращает true, если объект представляет интерфейс

  • boolean isEnum(): возвращает true, если объект представляет перечисление

  • boolean isRecord(): возвращает true, если объект представляет класс record

  • boolean isInstance(Object obj): возвращает true, если объект-параметр является экземпляром этого типа

  • boolean isSealed(): возвращает true, если класс определен с модификатором sealed

  • Class getSuperclass(): возвращает суперкласс для текущего типа

Пример применения некоторых из этих методов:

import java.lang.reflect.*;

public class Program{
      
    public static void main(String[] args) {
        
        // получаем класс для типа Person
        Class cl = Person.class;


        // получаем имя класса
        System.out.println("Name: " + cl.getName());
        // получаем суперкласс
        System.out.println("superclass: " + cl.getSuperclass());
        // проверяем, является ли тип примитивным типом
        System.out.println("primitive: " + cl.isPrimitive());
        // проверяем, является ли тип массивом
        System.out.println("array: " + cl.isArray());
        // проверяем, является ли тип классом record
        System.out.println("record: " + cl.isRecord());
        // проверяем, является ли тип интерфейсом
        System.out.println("interface: " + cl.isInterface());

        // проверям, что tom - объект класса
        Person tom = new Person("Tom", 41);
        System.out.println("tom is a Person:: " + cl.isInstance(tom));

        // проверям, что message - объект класса
        String message = "hello";
        System.out.println("message is a Person:: " + cl.isInstance(message));
    }
}
record Person(String name, int age){}

Консольный вывод программы:

Name: Person
superclass: class java.lang.Record
primitive: false
array: false
record: true
interface: false
tom is a Person:: true
message is a Person:: false
Помощь сайту
Юмани:
410011174743222
Номер карты:
4048415020898850