我有两个在语义上非常相似但语法不同的java类。差异很小,比如 -
变量名称的变化,
某些陈述的位置变化(中间没有相关的行),
额外进口等
我需要比较这两个类来证明它们确实在语义上是相同的。对于大量的java文件对,也需要做同样的事情。
从两个文件中读取并比较这些行的第一种方法,以及处理上述差异的逻辑似乎效率低下。还有其他方法可以实现这个任务吗?那里有任何有用的API吗?
答案 0 :(得分:1)
答案 1 :(得分:1)
那里有很多相似性检查器,到目前为止还没有完美的工具。每个都有自己的优点/缺点。这些方法通常分为两类:基于令牌或基于树。
基于令牌的相似性检查通常使用正则表达式完成,但其他方法也是可行的。在我在大学的一个项目中,我们开发了一个利用生物信息学领域的对齐策略。这种技术的缺点主要在于两个源的大小不相等或相等。
基于树的更像是编译器,所以通常使用一些编译技术可以(好吧,或多或少)检查这个。基于树的方法具有在比较复杂性方面具有指数性的缺点。
答案 2 :(得分:1)
逐行比较不会起作用。我想你可能需要使用解析器。我建议你看看ANTLR。它应该有一个java语法,您可以在其中放置将进行比较的动作。
答案 3 :(得分:1)
编译两个没有调试信息的类,然后将它们反编译回源文件。反编译的文件应该比原始源文件更相似。
您可以通过对已编译的文件运行一些优化来进一步改进。例如,您可以使用Proguard启用缩小功能来删除未使用的代码。
虽然很难发现某些陈述的位置变化。
答案 4 :(得分:1)
据我所知,现在可以比较两个Java类的语义。例如,采用以下两种方法:
public String m1(String a, int b) { ... }
和
public String m2(String x, int y) { ... }
变量和方法名称的变化部分,它们的签名是相同的:相同的返回类型和相同的输入类型。但是,这并不能保证这两种方法在语义上是等价的。例如,m1
可以返回由b
的第一个a
字符组成的字符串,而m2
可以返回由y
重复x
组成的字符串1}}。如您所见,虽然只有变量和名称发生变化,但这两种方法的语义完全不同。
我没有看到解决问题的简单方法。您可以做出一些假设并尝试以下方法:
这种方法可以让你对等效语义有所了解,但它有很强的假设。
作为最后一点,我要补充一点,指定程序的语义是一个有趣而开放的研究课题。该领域的一些有趣发展包括对Semantic Web Services的研究。为程序提供机器可处理语义的一种广泛采用的方法是指定它们的IOPE:输入和输出类型(如上面的Java方法中所述),以及它们的前置条件和效果。前提条件本质上是成功调用程序必须适用的逻辑条件,而Effects是对程序成功执行所引起的更改(在世界状态中)的正式描述。即使有了IOPE,也存在许多问题......我在这篇简短的描述中略过了这些问题。