Проще говоря: потому что иногда вы не знаете ни «Foo», ни «hello» во время компиляции.
В подавляющем большинстве случаев вы знаете это, так что это не стоит с помощью отражения. Но иногда вы этого не делаете - и при этом точка, отражение - это все, к чему вы можете обратиться.
Например, буферы протокола позволяют вам сгенерировать код, который либо содержит полный статически типизированный код для чтения и записи сообщений, либо генерирует ровно столько, чтобы остальное можно было сделать путем отражения: in В случае отражения код загрузки / сохранения должен получать и устанавливать свойства через отражение - он знает имена задействованных свойств из-за дескриптора сообщения. Это намного (намного) медленнее, но в результате генерируется значительно меньше кода.
Другим примером может быть внедрение зависимостей, где имена типов, используемых для зависимостей, часто предоставляются в файлах конфигурации: структура DI затем должна использовать отражение для создания всех задействованных компонентов, поиска конструкторов и / или свойств вдоль способ.
Я уже использовал его в некоторых проверочных классах раньше, где я передавал большую сложную структуру данных в конструктор и затем запустил миллион (на самом деле пару сотен) методов, чтобы проверить достоверность данных. Все мои методы проверки были частными и возвращали логические значения, поэтому я создал один метод «проверки», который вы могли вызвать, который использовал отражение для вызова всех частных методов в классе, а не возвращал логические значения.
Это сделало метод проверки более кратким (не нужно было перечислять каждый маленький метод) и гарантировало, что все методы выполняются (например, кто-то пишет новое правило проверки и забывает вызвать его в основном методе).
После перехода на использование отражения я не заметил значительной потери производительности, и код стало легче поддерживать.
Используя отражение, вы можете очень легко написать конфигурации, которые подробно описывают методы / поля в тексте, а структура, использующая их, может читать текстовое описание поля и находить реальное соответствующее поле.
например. JXPath позволяет вам перемещаться по объектам следующим образом:
//company[@name='Sun']/address
поэтому JXPath будет искать метод getCompany ()
(соответствующий company
), поле в котором называется name
и т. Д.
Вы найдете это во многих фреймворках Java, например JavaBeans, Spring и т. Д.
Вы можете использовать отражение для автоматизации любого процесса, который может с пользой использовать список методов и / или свойств объекта. Если вы когда-либо тратили время на написание кода, который по очереди делает примерно одно и то же с каждым из полей объекта - очевидный способ сохранения и загрузки данных часто работает именно так, - то это то, что отражение могло бы сделать для вас автоматически.
Наиболее распространенными приложениями, вероятно, являются следующие три:
XmlSerializer
) Он используется всякий раз, когда вы (= ваш метод / ваш класс) не знаете во время компиляции type должен создавать экземпляр или метод, который он должен вызывать.
Кроме того, многие фреймворки используют отражение для анализа и использования ваших объектов.Например:
String
, и вы можете получить целевой класс, получить метод с настроенным именем и вызвать его, не зная об этом во время компиляции. Типичное использование - это механизм подключаемого модуля, который поддерживает классы (обычно реализации интерфейсов), которые неизвестны во время компиляции.
в дополнение к ответу Джонса другое использование - это возможность «окунуть ногу в воду», чтобы проверить, присутствует ли данное средство в JVM. .
В OS X Java-приложение выглядит лучше, если вызываются некоторые классы, предоставленные Apple. Самый простой способ проверить наличие этих классов - сначала протестировать с отражением
Это полезно для таких вещей, как сериализация и объектно-реляционное сопоставление. Вы можете написать универсальную функцию для сериализации объекта, используя отражение для получения всех свойств объекта. В C ++ вам придется написать отдельную функцию для каждого класса.
Иногда вам нужно создать объект класса "на лету" или из другого места, не являющегося кодом Java (например, jsp). в это время полезно размышление.