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

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

变量名的变化,

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

额外进口等

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

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

【问题讨论】:

    标签: java compiler-construction syntax semantics


    【解决方案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,也存在很多问题......我在这个简短的描述中略过。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-01-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-15
              • 2010-12-25
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多