Поля класса и класс Field

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

За работу с полями классов в пакете java.lang.reflect отвечает класс Field. Для получения информации о полях и управления ими этот класс определеяет ряд методов, из которых отмечу основные:

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

  • Class getType(): возвращает тип поля в виде объекта Class

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

  • Set<AccessFlag> accessFlags(): возвращает набор флагов доступа для этого поля

  • Object get(Object obj): возвращает имя поля

  • void set(Object obj, Object value): возвращает имя поля

Получение полей

Для манипулирования полями нам прежде всего надо получить их. Для получения полей типа применяется ряд методов класса Class:

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

  • Field[] getDeclaredFields(): возвращает массив объектов Field для всех полей данного класса. Метод возвращают массив нулевой длины, если таких полей нет или если объект представляет собой примитивный тип или массив.

  • Field getField(String name): возвращает объект Field для публичного поля, имя которого передается в качестве параметра. Поиск также идет среди полей суперклассов. Если подобное публичное поле отсутствует, то метод генерирует исключение NoSuchFieldException

  • Field getDeclaredField(String name): возвращает объект Field для поля, имя которого передается в качестве параметра. Если подобное поле отсутствует, то метод генерирует исключение NoSuchFieldException

Например, получим поля класса:

import java.lang.reflect.*;

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

        // получаем поля 
        Field[] fields = cl.getDeclaredFields();
        for(Field f : fields){

            // получаем тип и имя поля
            System.out.printf("%s %s;\n", f.getType().getName(), f.getName());
        }
    }
}

class Person {
     
    private String name;
    private int age;

    public Person(String name, int age){ 

        this.name = name;
        this.age = age;
    }
    
    void print(){
        System.out.printf("Person. Name: %s;  Age: %d\n", name, age);
    }
} 

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

java.lang.String name;
int age;

Теперь получим по отдельности поля, используя их имя:

import java.lang.reflect.*;

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

        try{
            // получаем поля name и age
            Field nameField = cl.getDeclaredField("name");
            Field ageField = cl.getDeclaredField("age");

            System.out.println(nameField);
            System.out.println(ageField);
        }
        catch(NoSuchFieldException ex){
            System.out.println(ex);
        }
    }
}

class Person {
     
    private String name;
    private int age;

    public Person(String name, int age){ 

        this.name = name;
        this.age = age;
    }
    
    void print(){
        System.out.printf("Person. Name: %s;  Age: %d\n", name, age);
    }
} 

В данном случае с помощью метода getDeclaredField() получаем поля name и age класса Person. Обратите внимание, что при передаче имени поля учитывается регистр имени. В итоге на консоль будет выведена информация о полученных полях:

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

Манипуляции с полями

Манипуляции обычно включают получение значения поля или его установку. для этого класс Field предоставляет методы get()/set().

Обращение к приватным полям

По умолчанию механизм рефлексии учитывает контроль доступа Java. Так, при обращении к закрытым полям методы get() и set() по умолчанию вызываюют исключение IllegalAccessException - исключение недопустимого доступа. И по умолчанию методы get и set можно использовать только с доступными полями. Механизм безопасности Java позволяет узнать, какие поля есть у объекта, но не позволяет читать и записывать значения этих полей без соответствующего разрешения.

Но мы можем переопределить контроль доступа, вызвав метод setAccessible() для объекта Field и передав в метод true:

field.setAccessible(true);

Вызов setAccessible вызывает исключение, если доступ не предоставлен. Доступ может быть запрещён модульной системой.

Получение значения поля

Для получения значения поля применяется метод get(), который имеет следующее определение:

public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException

В качестве параметра в метод передается объект, значение поля которого надо получить. Например, получим значения полей объекта Person:

import java.lang.reflect.*;

public class Program{
      
    public static void main(String[] args) {
        
        // Исследуемый объект
        Person tom = new Person("Tom", 41);
        // получаем класс для типа Person
        Class cl = tom.getClass();

        try{
            // получаем поля name и age
            Field nameField = cl.getDeclaredField("name");
            Field ageField = cl.getDeclaredField("age");

            // делаем поля доступными для доступа
            nameField.setAccessible(true);
            ageField.setAccessible(true);

            // получаем значения полей
            Object name = nameField.get(tom);  // Tom
            Object age = ageField.get(tom);     // 41

            System.out.println("Name: " + name);
            System.out.println("Age: " + age);  
        }
        catch(Exception ex){
            System.out.println(ex);
        }
    }
}

class Person {
     
    private String name;
    private int age;

    public Person(String name, int age){ 

        this.name = name;
        this.age = age;
    }
    
    void print(){
        System.out.printf("Person. Name: %s;  Age: %d\n", name, age);
    }
} 

Изменение поля

Для изменения значения поля применяется метод set():

public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException

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

import java.lang.reflect.*;

public class Program{
      
    public static void main(String[] args) {
        
        // Исследуемый объект
        Person tom = new Person("Tom", 41);
        // получаем класс для типа Person
        Class cl = tom.getClass();

        try{
            // получаем поля name и age
            Field nameField = cl.getDeclaredField("name");
            Field ageField = cl.getDeclaredField("age");

            // делаем поля доступными для доступа
            nameField.setAccessible(true);
            ageField.setAccessible(true);

            // изменяем значения полей
            nameField.set(tom, "Bob");
            ageField.set(tom, 22);

            tom.print();    // Person. Name: Bob;  Age: 22
        }
        catch(Exception ex){
            System.out.println(ex);
        }
    }
}

class Person {
     
    private String name;
    private int age;

    public Person(String name, int age){ 

        this.name = name;
        this.age = age;
    }
    
    void print(){
        System.out.printf("Person. Name: %s;  Age: %d\n", name, age);
    }
} 

Таким образом, благодаря рефлексии приватность полей является преградой для их изменения.

Помощь сайту
Юмани:
410011174743222
Номер карты:
4048415020898850
Morty Proxy This is a proxified and sanitized view of the page, visit original site.