2011-06-20 163 views
4

我有兩個在語義上非常相似但語法不同的java類。差異是次要的,就像 -兩個Java類的比較

變化的變量名,

變化某些語句(中間無依賴線)的位置,

額外進口等

我需要比較這兩個類來證明它們的確在語義上是相同的。大量的java文件對需要完成相同的工作。

第一種從兩個文件中讀取數據並比較這些數據行與處理上述差異的邏輯似乎效率不高。有什麼其他方式可以實現這一任務嗎?那裏有任何有用的APIs?

回答

1

在沒有調試信息的情況下編譯這兩個類,然後將它們反編譯回源文件。反編譯的文件應該比原始源文件更加類似。

您可以通過對已編譯文件進行一些優化來進一步改善這一點。例如,您可以使用Proguard,只是啓用收縮以刪除未使用的代碼。

雖然某些語句的位置變化很難檢測到。

1

如果您想檢查代碼中的更改,請嘗試Araxis Merge或WinMerge

但是,如果你想邏輯的差異,恐怕你可能不得不手動。

我會建議使用這些工具之一來查找文本更改,然後查找邏輯差異。

1

這裏有很多相似性檢查器,直到現在還沒有完美的工具。每個人都有自己的優點/缺點。這些方法通常分爲兩類:基於標記的或基於樹的。

基於令牌的相似性檢查通常使用正則表達式來完成,但其他方法也是可能的。在我的一個大學項目中,我們開發了一個利用生物信息學領域的對齊策略。這種技術的缺點主要在於兩種來源的大小不大或相等。

基於樹的更像是一個編譯器,所以通常使用一些編譯技術來檢查它是可能的(或多或少)。基於樹的方法具有在比較複雜度上呈指數級的缺點。

1

逐行比較不會工作。我想你可能需要使用解析器。我建議你看看ANTLR。它應該有一個Java語法,你可以把你的行爲做比較。

1

據我所知現在有方法可以比較兩個Java類的語義。舉個例子如下兩種方法:

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

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

的一部分從變量和方法名稱的變化,他們的招牌是一樣的:相同的返回類型,以及相同的輸入類型。然而,這並不能保證這兩種方法在語義上是等價的。例如,m1可能會返回由a的第一個b個字符組成的字符串,而m2可能會返回由y重複的x組成的字符串。正如你所看到的,雖然只有變量和名稱會改變,但這兩種方法的語義完全不同。

我看不出您的問題的簡單方法。你可以或許做一些假設,試試下面的辦法:

  • 假定在這兩個類中的方法名是相同的
  • 寫測試用例(例如使用JUnit)在第一類中的所有方法
  • 運行在第二類
  • 測試用例確保第二類不具有其他(未經測試)的方法(例如使用反射)

這種方法提供了有關的想法等價的語義,但它是有力的假設。

作爲最後一句話,讓我補充一點,指定程序的語義是一個有趣且開放的研究課題。這方面的一些有趣的發展包括對Semantic Web Services的研究。一種廣泛採用的將機器可處理的語義賦予程序的方法是指定其IOPE:輸入和輸出類型(如上面的Java方法int)及其先決條件和效果。先決條件本質上是符合成功調用程序的邏輯條件,而效果是對成功執行程序引起的變化(在世界的狀態)的形式描述。即使有IOPE,也存在很多問題......我在這個簡短的描述中略過。