Моя путаница: отражение в Java

Я только что закончил читать главу «Мышление в Java», посвященную информации о типах и отражению. Хотя instanceof кажется мне вполне естественным, некоторые примеры отражения меня смутили. Я хочу знать, широко ли используется отражение в проектах Java? Каковы «хорошие части» отражения? Можете ли вы предложить какие-нибудь интересные лекции по размышлению и набрать информацию с более хорошими и достойными примерами?

Изменить (еще один вопрос):

Почему полезно обращаться к закрытым методам и полям с помощью java.lang.reflect.Method.setAccesible()?

Заранее спасибо.


person Maciej Ziarko    schedule 01.05.2011    source источник
comment
если вы также можете опубликовать пример, который сбивает вас с толку, мы все можем обсудить это.   -  person Heisenbug    schedule 01.05.2011
comment
Например: pastebin.com/3whc59LN Это иллюстрирует динамический прокси для создания нулевого объекта. Это популярное решение? мне это показалось странным   -  person Maciej Ziarko    schedule 01.05.2011
comment
Масиэль. Подумайте об этом сценарии: у вас есть только двоичные файлы для некоторого класса, одно из частных полей объекта этого класса содержит неправильное значение, и/или вам нужно вызвать частный метод одного объекта по какой-либо причине. Затем вы можете установить их как доступные, изменить значение переменной и вызвать частный метод с помощью отражения. Конечно, это нарушает принципы объектно-ориентированного программирования и имеет свои недостатки (перейдите по ссылке Oracle Trails в моем ответе и прочитайте о раскрытии внутренних компонентов), но это действительно полезно.   -  person Anthony Accioly    schedule 01.05.2011
comment
Воспользуюсь вашей ссылкой, спасибо!   -  person Maciej Ziarko    schedule 01.05.2011
comment
@см. Использование отражения: download.oracle.com/javase/tutorial/reflect   -  person simpatico    schedule 02.05.2011


Ответы (4)


если бы вы могли опубликовать некоторые из примеров, я был бы рад объяснить это для вас. Отражение широко используется с фреймворками, которым необходимо извлекать метаинформацию о запущенном объекте (например, фреймворки, которые зависят от аннотаций или полей в ваших объектах, подумайте о Hibernate, Spring и многих других). На более высоком уровне я иногда использую отражение для обеспечения универсальной функциональности (например, для кодирования каждой строки в объекте, эмуляции Duck Typing и т. д.). Я знаю, что вы уже читали книгу, в которой рассматриваются основы отражения, но мне нужно указать официальное руководство Sun (эм... Oracle) как обязательное к прочтению: http://download.oracle.com/javase

person Anthony Accioly    schedule 01.05.2011
comment
pastebin.com/3whc59LN В этом примере показан динамический прокси для создания нулевого объекта. Это популярное решение? Мне это показалось странным. - person Maciej Ziarko; 01.05.2011
comment
Думайте о коде, который вы предоставили, как о динамическом подходе к этим шаблонам проектирования: en.wikipedia.org/wiki/Null_Object_pattern, en.wikipedia.org/wiki/Decorator_pattern. Ваш код предоставляет нулевой объект, а прокси-серверы в целом могут использоваться для декорирования объектов. - person Anthony Accioly; 01.05.2011
comment
Привет, пример довольно академический, и да, прокси — это то, что часто используется фреймворками. Думайте о прокси как об инструменте, позволяющем обернуть динамическую функциональность вокруг метода. Например, Hibernate создает динамические прокси вокруг объектов вашей модели, эти прокси извлекают ленивые ассоциации из базы данных, когда вы вызываете object.getXXX(). Прокси работают так, они получают исходный объект и создают новый, который для каждого целевого метода делает что-то дополнительное до/после или вместо функциональности исходного объекта (вызывается в строке 45). - person Anthony Accioly; 01.05.2011

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

person Jad    schedule 01.05.2011
comment
1+. Class.forName(...).newInstance() + ResourceBundle, вероятно, является одним из основных способов использования для меня (и я забыл сказать об этом в своем ответе). - person Anthony Accioly; 01.05.2011
comment
Проголосовал за упоминание фреймворков, которые я забыл в своем ответе :) Они довольно активные пользователи этого метода программирования. - person Jad; 01.05.2011

Другой пример может быть, когда вам нужно привести объект к классу, который является потомком. Если вы не уверены в типе этого объекта, вы можете использовать instanceof, чтобы убедиться, что приведение будет правильным во время выполнения, избегая исключения приведения класса.

Пример:

public void actionPerformed (ActionEvent e){
    Object obj = e.getSource();

    if (obj instanceof objType)
    objType t = (objType) obj;   // you can check the type using instanceof if you are not sure about obj class at runtime
}
person Heisenbug    schedule 01.05.2011

Причина предоставления таких функций в Reflection связана с несколькими ситуациями, когда инструменту/приложению требуется метаинформация о классе, переменных, методах. Например:-

  1. IDE, использующие функцию автоматического завершения для получения имен методов и имен атрибутов.
  2. Веб-контейнер Tomcat для пересылки запроса на правильный модуль путем анализа их файлов web.xml и запроса URI.
  3. JUnit использует отражение для перечисления всех методов в классе; предполагая либо именованные методы testXXX в качестве тестовых методов, либо методы, аннотированные @Test.

Чтобы прочитать полную статью об отражении, вы можете проверить http://modernpathshala.com/Forum/Thread/Interview/308/give-some-examples-where-reflection-is-used

person amitguptageek    schedule 05.01.2016
comment
Можем ли мы избежать использования сокращенных URL-адресов. Я боюсь нажимать на ссылку, потому что кто знает, что на другом конце. - person d0nut; 05.01.2016