两个 Java 类的比较

Posted

技术标签:

【中文标题】两个 Java 类的比较【英文标题】:Comparison of two Java classes 【发布时间】:2011-09-18 10:36:39 【问题描述】:

我有两个语义非常相似但语法不同的 java 类。差异很小,例如 -

变量名的变化,

一些语句的位置变化(中间没有依赖行),

额外进口等

我需要比较这两个类来证明它们在语义上确实是相同的。对于大量的 java 文件对也需要这样做。

从两个文件中读取并比较行的第一种方法,以及处理上述差异的逻辑似乎效率低下。还有其他方法可以完成这项任务吗?有什么有用的 API 吗?

【问题讨论】:

【参考方案1】:

在没有调试信息的情况下编译这两个类,然后将它们反编译回源文件。反编译后的文件应该比原始源文件更相似。

您可以通过对编译后的文件进行一些优化来进一步改进这一点。例如,您可以使用 Proguard 并启用收缩功能以删除未使用的代码。

虽然有些语句的位置变化很难检测到。

【讨论】:

【参考方案2】:

如果您想检查代码中的更改,请尝试 Araxis Merge 或 WinMerge。

但如果你想要逻辑差异,恐怕你可能不得不手动完成。

我建议使用其中一种工具来查找文本更改,然后查找逻辑差异。

【讨论】:

【参考方案3】:

那里有很多相似性检查器,直到现在还没有完美的工具。每个都有自己的优点/缺点。这些方法通常分为两类:基于令牌的或基于树的。

基于标记的相似性检查通常使用正则表达式完成,但也可以使用其他方法。在我在大学的一个项目中,我们开发了一种利用生物信息学领域的对齐策略。这种技术的缺点主要是两个源的大小不相等。

基于树的更像是一个编译器,因此通常使用一些编译技术可以(嗯,或多或少)检查这一点。基于树的方法的缺点是比较复杂度呈指数增长。

【讨论】:

【参考方案4】:

逐行比较是行不通的。我认为您可能需要使用解析器。我建议你看看ANTLR。它应该有一个 java 语法,您可以在其中放置将进行比较的操作。

【讨论】:

【参考方案5】:

据我所知,现在有办法比较两个 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 方法),以及它们的前提条件和效果。先决条件本质上是成功调用程序必须成立的逻辑条件,而效果是对程序成功执行引起的变化(在世界状态中)的正式描述。即使使用 IOPE,也存在很多问题......我在这个简短的描述中略过。

【讨论】:

以上是关于两个 Java 类的比较的主要内容,如果未能解决你的问题,请参考以下文章

如何判断两个对象的值是不是相等java

java中两个字符串如何比较大小

如何查看java一个类的大小

如何查看java一个类的大小

java中两个字符串如何比较大小?

java里的Collections类中的静态方法sort()是怎么用比较器比较两个对象?