Страницы

Поиск по вопросам

понедельник, 8 октября 2018 г.

В каких случаях на практике применять рефлексию, аннотации?

Помогите уяснить.
К примеру, одно из частных определений рефлексии говорит: "Рефлексия - это инструмент с помощью которого можно узнать всю информацию о классе: имена методов, параметры, поля, аннотации....".
У меня, как у новичка, возникает резонный вопрос, зачем мне эту информацию узнавать, если классы, методы, поля и т.д. я пишу сам и всё про них знаю?
Понимаю, что используется рефлексия не для своих классов и т.д., но не могу найти реальный пример, который был бы понятен новичку: в какой ситуации я столкнусь с тем, что не буду знать имя класса, метода и т.д.?
То же самое с аннотациями: "...средство, позволяющее встраивать справочную информацию в исходные файлы......". Ну встрою я её, ну а профит какой, что я в итоге с помощью этого получу? Какие плюшки для разработчика появятся при наличии аннотаций? Как они способны облегчить жизнь?


Ответ

Рефлексия и аннотации позволяют решать задачи, который в иных случаях можно было бы решить либо ручным монотонным кодированием, либо кодогенерацией.
И, конечно, когда они используются, то применяются не к конкретным классам, а с запасом, даже к тем классам, которые вы напишете в будущем. Часто их используют в библиотечном коде, который будет бродить между проектами и, соответственно, о классах тех проектов вообще не знать ничего.
Несколько конкретных примеров:
Аннотации Hibernate
Hibernate — это ORM, то есть библиотека для удобного отображения баз данных на объектный код. Часто в базе и в Java-коде применяются разные соглашения об именовании. Для того, чтобы Hibernate понимал, какое поле куда копировать, применяют аннотации. Для таблицы:
create table EMPLOYEE ( id INT NOT NULL auto_increment, first_name VARCHAR(20) default NULL, last_name VARCHAR(20) default NULL, salary INT default NULL, PRIMARY KEY (id) );
Можно применить аннотации:
@Entity @Table(name = "EMPLOYEE") public class Employee { @Id @GeneratedValue @Column(name = "id") private int id;
@Column(name = "first_name") private String firstName;
@Column(name = "last_name") private String lastName;
@Column(name = "salary") private int salary;
public Employee() {} public int getId() { return id; } public void setId( int id ) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName( String first_name ) { this.firstName = first_name; } public String getLastName() { return lastName; } public void setLastName( String last_name ) { this.lastName = last_name; } public int getSalary() { return salary; } public void setSalary( int salary ) { this.salary = salary; } }
Пример взят отсюда. Кратко, что здесь происходит: в базе данных поле называется, например, first_name, а в Java-коде — firstName. Благодаря аннотациям при загрузке записей из базы в объект Employee библиотека самостоятельно раскидает все поля как надо.
Компилятор Java
Компилятор также использует аннотации для дополнительных проверок или для изменения своих настроек внутри отдельных методов. Смотрите аннотации @Override и @SuppressWarnings
AndroidAnnotations
Проект http://androidannotations.org/ позволяет значительно упростить разработку кода для Android, реализовав частые задачи, и обернув их в аннотации. Это как раз хороший пример библиотечного кода, который будет работать в незнакомых проектах. Естественно, для реализации этого кода активно применяется рефлексия. Пример «до аннотаций» и «после аннотаций» приведён прямо на главной странице по ссылке выше.
Аспектно-ориентированное программирование
Про него много писать не буду, поскольку тема очень большая и новичку может быть не сильно нужная. Но в целом АОП как раз об этом. Например, вы можете написать свои классы, а потом озаботится проверкой прав доступа, навроде администратор может удалять записи, а обычный пользователь — нет
При классическом подходе вам придётся вносить однотипные изменения в большое количество существующих классов, а потом не забывать делать это для новых. В АОП вы можете просто придумать аннотации @Administrator, @User, @Moderator и расставить их у нужных классов и методов. Это тоже монотонно, но всё равно гораздо проще.
Рефлексия без аннотаций
Рефлексия применяется ещё чаще, например, в разного рода шаблонизаторах и мапперах. Шаблонизаторы позволяют вам использовать шаблоны писем, например, как этот:
Здравствуйте, %username%!
Напоминаем Вам, что вы задолжали нам крупную сумму денег в размере %amount% рублей. Мы помним!
С уважением, Коллекторское агентство «Солнышко»
Затем вы передаете шаблонизатору класс с полями username и amount и он самостоятельно сформирует текст письма. Такую задачу без рефлексии не сделать.
Заключение
В целом, рефлексия и аннотации позволяют избавиться от так называемого monkey coding, то есть от монотонного низкоуровнего кодирования.

Комментариев нет:

Отправить комментарий