有没有一种方法可以使用Eclipse列出某个类的所有equals()调用?

10
我现在面临以下问题:
我有一个特定的类,在该类中重写了equals()方法。但是我不确定它是否被使用过(无论是在我的项目还是在我的同事的项目中)。有没有办法找出来呢? 当我搜索引用时,它只会给我所有与Object equals()方法相关的引用(这些引用相当多)。肯定有一种更简单的方式,而不是扫描所有引用... 有人有想法吗?
5个回答

7
您正在要求Eclipse解决一项不可能的任务。
确定特定的覆盖方法是否被调用是无法进行静态判断的,这就是为什么Eclipse会对响应进行过度近似的原因。
假设您有一个字段Object o,并且在某个时候执行o.equals(...)。要确定o是否可能引用YourClass对象需要确定o的运行时类型沿着每条可能的执行路径,这在静态上是不能完成的。
其原因与编译器拒绝以下代码的原因非常相似:
Object o = "hello";
System.out.println(o.length());

你最好能够调试你的程序,可以通过设置断点或在equals方法内部抛出UnsupportedOperationException异常来实现。


我认为问题是关于工作区项目中的引用,而不是运行时调用。 - guido
1
这也是我理解的问题。 - aioobe
你的例子让我更加认为运行时类型与这个问题无关。虽然在子类重写该方法时跟踪 super() 调用可能会很麻烦(但并非不可能)。即使子类进行了向下转型并调用了 equals() 方法,在那一行代码中,局部变量在静态上仍可识别为目标类。所以,你能提供一个具体的例子来让我理解你的观点吗? - guido
1
你漏掉的是搜索引用仅能够找到静态可知的引用。换句话说,编译器知道你有一个MyClass的实例,并且代码中该引用在显式调用equals()。然而,由于equals()定义在Object上,它可以在任何可能或可能没有分配给MyClass实例的Object变量上调用。例如,有些集合会对其内容调用equals()但不知道内容的类是什么。 - E-Riz
1
@guido,在原始问题的背景下,“不可能”这个答案绝对不是过度解释。问题已经说明简单的引用搜索无法得到提问者想要的结果,他说“肯定有比扫描所有内容更简单的方法……”——答案是,“没有。” - E-Riz
显示剩余7条评论

3

似乎在这方面Java出了问题。因此你需要用较困难的方法来尝试捕捉所有情况。

  • 创建类的副本
  • 删除旧类
  • 逐一重命名以解决所有编译器错误
  • 查找将类用作映射键的情况
  • 查找该类的集合(indexOf(),contains())
  • 查找对该类的equals()或hashCode()的调用
  • 希望你没有漏掉什么

2
我无法想到一种仅通过静态分析就能可靠地完成这个任务的方法(我怀疑这样的方法是否存在)。
一个实用的方法是,在equals()方法的第一行设置一个断点,并在Eclipse调试器中启动程序。每当方法被调用时,Eclipse都会进入调试器。此时,您可以检查调用堆栈以查看谁调用了该方法。
要有效地执行此操作,您必须对哪些代码路径可能调用该方法有一些了解。如果您无法触发该方法,则不能证明没有人使用它。

2
然后呢?在调试模式下执行每个可能的代码路径吗? - Asaph
@Asaph:恕我直言,如果您有更好的建议,非常欢迎您发表。 - NPE
1
我本来想回答,但我认为@aioobe已经给出了答案(即无法完成)。我点赞了他的回答。 - Asaph

1
在Eclipse中选择方法名->包资源管理器或大纲视图并单击F4。 或者您可以选择方法->右键单击->打开调用层次结构 这将显示在您的工作区中调用此方法的所有成员。 希望这可以帮助到您。

1

将重写的 equals 方法修改为类似以下内容:

log.debug // Whatever you want
return this == obj;

你使用经典的对象相等方法吗?或者如果你继承了某个类,使用super.equals方法?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接