2010-03-21 3 views
8

Мне было просто интересно, почему мы должны использовать reflection в первую очередь?Что такое отражение в Java/C# и т. Д.

// Without reflection 
Foo foo = new Foo(); 
foo.hello(); 

// With reflection 
Class cls = Class.forName("Foo"); 
Object foo = cls.newInstance(); 
Method method = cls.getMethod("hello", null); 
method.invoke(foo, null); 

Мы можем просто создать объект и вызвать метод класса, но почему одни и те же функции, используя forName, newInstance и getMthod?

Чтобы сделать все динамичным?

ответ

27

Проще говоря: потому что иногда вы не знаете частей «Foo» или «hello» во время компиляции.

Подавляющее большинство из вас do знают это, поэтому не стоит использовать отражение. Однако иногда, однако, вы этого не делаете - и в этот момент размышление - это все, к чему вы можете обратиться.

В качестве примера protocol buffers позволяет генерировать код, который либо содержит полный статически типизированный код для чтения и записи сообщений, либо генерирует его достаточно, чтобы остальное могло быть выполнено путем отражения: в случае отражения загрузка/save код должен получить и установить свойства через отражение - он знает имена свойств, связанных с дескриптором сообщения. Это намного (намного) медленнее, но приводит к значительно меньшему генерированию кода.

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

+0

Почему это было приостановлено? – SLaks

+0

+1, так как это так. –

+0

@Jon: Разве это не дубликат? –

3

Типичное использование - это подключаемый механизм, который поддерживает классы (обычно реализации интерфейсов), которые неизвестны во время компиляции.

0

в дополнение к Jons ответ, другое использование - это возможность «окунуться в воду», чтобы проверить, присутствует ли данный объект в JVM.

В OS X приложение Java выглядит лучше, если вызываются некоторые классы, предлагаемые Apple. Самый простой способ проверить, присутствуют ли эти классы, - сначала проверить с отражением

1

Это полезно для таких вещей, как сериализация и объектно-реляционное сопоставление. Вы можете написать общую функцию для сериализации объекта с помощью отражения, чтобы получить все свойства объекта. В C++ вам нужно написать отдельную функцию для каждого класса.

3

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

наиболее распространенных приложений, вероятно, эти три:

  • сериализация (смотрите, например, XmlSerializer .NET в)
  • Генерация виджетов для редактирования свойств объектов (например, диалогового Xcode в Interface Builder, .NET в дизайнер)
  • Заводы, которые создают объекты с произвольными зависимостями, изучая классы для конструкторов и поставляя подходящие объекты при создании (например,, любая конструкция для инъекций зависимостей)
2

Используя отражение, вы можете легко написать конфигурации, которые подробно описывают методы/поля в тексте, а структура, использующая их, может читать текстовое описание поля и находить реальное соответствующее поле.

например. JXPath позволяет перемещаться по объектам, как это:

//company[@name='Sun']/address 

так JXPath будет искать метод getCompany() (соответствующий company), поле в том, что называется name и т.д.

Вы найдете это в большом количестве в Java, например JavaBeans, Spring и т. Д.

4

Используется всякий раз, когда вы (= ваш метод/ваш класс) не знаете во время компиляции тип должен быть экземпляр или метод, который он должен вызывать.

Кроме того, многие структуры используют отражение для анализа и использования ваших объектов. Например:

  • спящем/NHibernate (и любой объектно-реляционной картографа) использовать отражение, чтобы проверить все свойства ваших классов, так что он может обновлять их или использовать их при выполнении операций базы данных
  • вы можете хотите настроить его, какой метод пользовательского класса выполняется по умолчанию вашим приложением. Настроенное значение равно String, и вы можете получить целевой класс, получить метод с настроенным именем и вызвать его, не зная об этом во время компиляции.
  • разбора аннотаций осуществляются путем отражения
1

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

Это сделало метод проверки более кратким (не нужно перечислять каждый маленький метод) и поручил все методы запускать (например, кто-то пишет новое правило проверки и забывает вызвать его в основном методе).

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

0

Несколько раз вам нужно создать объект класса на лету или из какого-либо другого места, а не код Java (например, jsp). в то время отражение полезно.

Смежные вопросы