Рубрики

Отражение на Яве

Reflection — это API, который используется для проверки или изменения поведения методов, классов, интерфейсов во время выполнения.

  • Необходимые классы для отражения предоставляются в пакете java.lang.reflect.
  • Reflection дает нам информацию о классе, к которому принадлежит объект, а также о методах этого класса, которые могут быть выполнены с использованием объекта.
  • Через отражение мы можем вызывать методы во время выполнения независимо от спецификатора доступа, используемого с ними.

Отражение может быть использовано для получения информации о —

  1. Класс Метод getClass () используется для получения имени класса, к которому принадлежит объект.
  2. Конструкторы Метод getConstructors () используется для получения открытых конструкторов класса, к которому принадлежит объект.
  3. Методы Метод getMethods () используется для получения открытых методов класса, к которому принадлежит объект.

// Простая Java-программа для демонстрации использования отражения

import java.lang.reflect.Method;

import java.lang.reflect.Field;

import java.lang.reflect.Constructor;

  
// класс, объект которого должен быть создан

class Test

{

    // создаем приватное поле

    private String s;

  

    // создаем публичный конструктор

    public Test()  {  s = "GeeksforGeeks"; }

  

    // Создание открытого метода без аргументов

    public void method1()  {

        System.out.println("The string is " + s);

    }

  

    // Создание открытого метода с аргументом int

    public void method2(int n)  {

        System.out.println("The number is " + n);

    }

  

    // создаем приватный метод

    private void method3() {

        System.out.println("Private method invoked");

    }

}

  

class Demo

{

    public static void main(String args[]) throws Exception

    {

        // Создание объекта, свойство которого нужно проверить

        Test obj = new Test();

  

        // Создание объекта класса из объекта с использованием

        // метод getclass

        Class cls = obj.getClass();

        System.out.println("The name of class is " +

                            cls.getName());

  

        // Получение конструктора класса через

        // объект класса

        Constructor constructor = cls.getConstructor();

        System.out.println("The name of constructor is " +

                            constructor.getName());

  

        System.out.println("The public methods of class are : ");

  

        // Получение методов класса через объект

        // класса с использованием getMethods

        Method[] methods = cls.getMethods();

  

        // Печать имен методов

        for (Method method:methods)

            System.out.println(method.getName());

  

        // создает объект нужного метода, предоставляя

        // имя метода и класс параметров в качестве аргументов

        // getDeclaredMethod

        Method methodcall1 = cls.getDeclaredMethod("method2",

                                                 int.class);

  

        // вызывает метод во время выполнения

        methodcall1.invoke(obj, 19);

  

        // создает объект нужного поля, предоставляя

        // имя поля в качестве аргумента

        // метод getDeclaredField

        Field field = cls.getDeclaredField("s");

  

        // позволяет объекту получить доступ к полю независимо

        // спецификатора доступа, используемого с полем

        field.setAccessible(true);

  

        // принимает объект и новое значение для назначения

        // к полю в качестве аргументов

        field.set(obj, "JAVA");

  

        // Создает объект нужного метода, предоставляя

        // имя метода в качестве аргумента для getDeclaredMethod

        Method methodcall2 = cls.getDeclaredMethod("method1");

  

        // вызывает метод во время выполнения

        methodcall2.invoke(obj);

  

        // Создает объект нужного метода, предоставляя

        // имя метода в качестве аргумента

        // метод getDeclaredMethod

        Method methodcall3 = cls.getDeclaredMethod("method3");

  

        // позволяет объекту обращаться к методу независимо

        // спецификатора доступа, используемого с методом

        methodcall3.setAccessible(true);

  

        // вызывает метод во время выполнения

        methodcall3.invoke(obj);

    }

}

Выход :

The name of class is Test
The name of constructor is Test
The public methods of class are : 
method2
method1
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
The number is 19
The string is JAVA
Private method invoked

Важные наблюдения:

  1. Мы можем вызвать метод через отражение, если знаем его имя и типы параметров. Мы используем ниже два метода для этой цели
    getDeclaredMethod (): для создания объекта метода, который будет вызван. Синтаксис этого метода
    Class.getDeclaredMethod(name, parametertype)
    name- the name of method whose object is to be created
    parametertype - parameter is an array of Class objects

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

    Method.invoke(Object, parameter)
    If the method of the class doesn’t accepts any 
    parameter then null is passed as argument.
  2. Через отражение мы можем получить доступ к закрытым переменным и методам класса с помощью объекта класса и вызвать метод с помощью объекта, как обсуждалось выше. Мы используем ниже два метода для этой цели.

    Class.getDeclaredField (FieldName): используется для получения приватного поля. Возвращает объект типа Field для указанного имени поля.
    Field.setAccessible (true): позволяет получить доступ к полю независимо от модификатора доступа, используемого с полем.

  3. Преимущества использования отражения:

  • Функции расширяемости. Приложение может использовать внешние пользовательские классы, создавая экземпляры объектов расширяемости, используя их полностью определенные имена.
  • Инструменты отладки и тестирования . Отладчики используют свойство отражения для проверки закрытых членов классов.

Недостатки:

  • Повышение производительности: отражающие операции имеют более низкую производительность, чем их неотражающие аналоги, и их следует избегать в тех разделах кода, которые часто вызываются в чувствительных к производительности приложениях.
  • Воздействие внутренних элементов: рефлексивный код нарушает абстракции и, следовательно, может изменить поведение при обновлении платформы.


Ссылка:

https://docs.oracle.com/javase/tutorial/reflect/index.html

Эта статья предоставлена Akash Ojha. Если вы любите GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью и отправить статью по почте на contrib@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

Рекомендуемые посты:

Отражение на Яве

0.00 (0%) 0 votes