Сравнение двух классов Java - PullRequest
4 голосов
/ 20 июня 2011

У меня есть два Java-класса, которые очень похожи по семантике, но отличаются по синтаксису.Различия незначительны, как -

Изменения в именах переменных,

Изменения в положении некоторых операторов (без зависимых строк между ними),

Дополнительный импорт и т. Д.

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

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

Ответы [ 5 ]

1 голос
/ 20 июня 2011

Насколько я знаю, теперь есть способ сравнить семантику двух классов Java.Возьмем, к примеру, следующие два метода:

public String m1(String a, int b) { ... }

и

public String m2(String x, int y) { ... }

Часть из изменений в именах переменных и методов, их сигнатура одинакова: тот же тип возврата и тот же вводтипы.Однако это не является гарантией того, что оба метода семантически эквивалентны.Например, m1 может возвращать строку, состоящую из первых b символов a, в то время как m2 может возвращать строку, состоящую из y повторений x.Как видите, хотя меняются только переменные и имена, семантика двух методов совершенно различна.

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

  • предположить, что имена методов в двух классах одинаковы
  • записать тестовые случаи (например, с JUnit) для всехметоды в первом классе
  • запускают контрольные примеры во втором классе
  • гарантируют, что во втором классе нет других (непроверенных) методов (например, с использованием отражения)

Этот подход дает вам представление об эквивалентной семантике, но он делает серьезное предположение.

В качестве последнего замечания позвольте мне добавить, что указание семантики программ является интересной и открытой темой исследования.Некоторые интересные разработки в этой области включают исследование Semantic Web Services .Широко принятый подход для придания программам семантики, обрабатываемой машиной, заключается в определении их IOPE: типов ввода и вывода (как в приведенных выше методах Java), а также их предварительных условий и эффектов.Предварительные условия - это, по сути, логические условия, которые должны выполняться для успешного вызова программы, а эффекты - это формальное описание изменений (в состоянии мира), вызванных успешным выполнением программы.Даже с IOPE есть много проблем ... которые я пропускаю в этом коротком описании.

1 голос
/ 20 июня 2011

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

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

Хотя изменения в положении некоторых операторов могут быть трудно обнаружить.

1 голос
/ 20 июня 2011

Существует множество средств проверки сходства, и до сих пор еще нет идеального инструмента для этого. У каждого есть свои преимущества / недостатки. Подходы обычно делятся на две категории: на основе токенов или на основе деревьев.

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

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

1 голос
/ 20 июня 2011

Сравнение построчно не сработает.Я думаю, вам может понадобиться парсер.Я бы посоветовал вам взглянуть на ANTLR .Он должен иметь грамматику Java, в которую вы можете поместить свои действия, которые будут выполнять сравнение.

1 голос
/ 20 июня 2011

Если вы хотите проверить изменения в коде, попробуйте Araxis Merg e или WinMerge .

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

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

...