Java Reflection и боль в рефакторинге - PullRequest
10 голосов
/ 22 июня 2009

Java Reflection предоставляет механизм для самоанализа объекта во время выполнения. Не задумываясь, это отличная функция, но она нарушает все соглашения по рефакторингу!

Нет простого способа (кроме File Search) даже в современных IDE узнать, на какой атрибут ссылаются и где. Это делает Refactorings намного более сложным (утомительным!) И подверженным ошибкам.

Если быть откровенным, это не просто Reflection API; Hibernate mapping files (hbm.xml) и JSP files оба ссылаются на атрибуты как на String, и когда вы реорганизуете имя атрибута, вам придется вручную изменить все эти места.

Хуже того, изменения в файлах отображения Hibernate или файлах JSP приводят к ошибкам во время выполнения.

Мне интересно знать, как другие программисты справляются с этим на Java. Есть ли инструменты? Я использую Eclipse / IBM RAD в качестве основной платформы разработки. Обычно мы используем constant для определения атрибута и используем его всякий раз, когда это возможно, но это не всегда возможно.

Мне также было бы интересно, как другие языки справляются с этим!

Ответы [ 9 ]

7 голосов
/ 22 июня 2009

Отражение Java вызывает много тех же проблем, которые возникают у динамически типизированных языков, таких как Python и Ruby. Фактически, один из способов думать о динамически типизированных языках - это то, что все вызывается с использованием отражения, а языки просто обеспечивают хороший, чистый синтаксис для отражения.

И да, с динамически типизированными языками (или интенсивным использованием рефлексии) рефакторинг труден. Вы не получите хороших возможностей рефакторинга Eclipse. Вместо этого grep становится вашим другом.

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

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

2 голосов
/ 01 июля 2011

На самом деле мы разработали плагин Eclipse, который в значительной степени решает эту проблему. Это называется RefaFlex: http://www.feu.de/ps/prjs/rf/

2 голосов
/ 22 июня 2009

Современные IDE имеют функцию, которая при переименовании класса будет искать полное имя, например, в ваших XML-файлах, чтобы попытаться переименовать любые ссылки, которые у вас могут быть в них. Не думайте, что это решит проблему - очень часто вы не ссылаетесь на имена классов.

Кроме того, именно поэтому необходимо проявлять особую осторожность и осмотрительность, прежде чем использовать его в своем собственном коде.

Но эта проблема с отражением - вот почему использование аннотаций становится все более популярным. Проблема уменьшается при использовании аннотаций.

Но позвольте мне сказать, как справедливо указывает предыдущий пост, если у вас нет хорошей системы безопасности для юнит-тестов, любой вид рефакторинга, независимо от того, используете вы много рефлексии или нет, опасен. *

1 голос
/ 22 июня 2009

Рефакторинг можно улучшить, введя больше «литералов» в язык. Например. imho .class literal - отличный способ обеспечить безопасность определенных моделей во время компиляции. Однако важно сказать, что иногда я хочу потерять безопасность во время компиляции . Строки - это самый простой, но эффективный способ выражения слабо связанных контрактов между двумя уровнями, поскольку вы можете манипулировать ими или сопоставлять их с регулярным выражением и т. Д.

Реальная проблема рефлексии - многословное использование API. Это основные затраты на гибкость.

PS

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

0 голосов
/ 31 марта 2011

Вы можете избежать написания API отражения с dp4j.com , когда вы знаете во время компиляции, что вы ищете.

Что касается отображений xml, они являются проблемой, я также испытывал это на платформе NetBeans и менее на JPA2. Хорошей новостью является то, что аннотации вступают во владение, и это предлагает снова проверку во время компиляции. Я не уверен насчет Hibernate, но и JPA, и NetBeans ( больше на 7 ) предлагают аннотации, эквивалентные сопоставлениям xml.

Я также разработал SqlWrapper , чтобы избежать использования строк с JDBC. Более сложным (и сложным) является API критериев JPA2.

0 голосов
/ 24 июня 2010

А как насчет классов, методов, полей taggin, к которым вы обращаетесь с помощью отражения? IDE может предупредить вас, когда вы поменяете их имена.

0 голосов
/ 22 июня 2009

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

Тем не менее, J2EE-версия Eclipse IDE вместе с подходящими плагинами для основных сред, таких как Hibernate, Spring и т. Д., Отлично справится с рефакторингом. Модульные тесты сократят цикл тестирования, но проблема в том, что иногда модульные тесты также зависят от некоторой конфигурации XML, заставляя вас использовать рефлексию. Таким образом, при рефакторинге можно прерывать юнит-тесты вместе с вашим кодом.

0 голосов
/ 22 июня 2009

Что ж, это еще одна возможность для IDE продавать дорогие премиальные версии, которые будут распознавать и реорганизовывать имена классов, используемые в определенных конфигурационных файлах.

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

Но не существует общего решения для прямого, "ручного" использования API отражения - именно поэтому он вообще не рекомендуется.

0 голосов
/ 22 июня 2009

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

...