FindBugs:检测Object.hashCode()的调用

时间:2014-07-02 08:23:46

标签: java static-analysis findbugs

如果一个对象没有实现它自己的hashCode()方法,那么它将使用默认实现Object.hashCode()(前提是它们之间没有超类)。 Object.hashCode()并不保证在不同的JVM实例中生成相同的哈希码。我们在集群环境中遇到了一些问题。

除了我们应用的一些修复,我们希望静态分析检测到这种情况。我们已经在使用FindBugs,但不幸的是我没有扩展默认规则集的经验。

我做过一些研究,我知道你可以实现自己的自定义探测器,但我没有找到很多关于如何做到这一点的文档。

我想我的问题是:

  • 在我在这里投入太多工作之前,这种方法是否合理,FindBugs可以这样做吗?
  • 让我开始编写自定义检测器的最佳资源是什么?

感谢您的投入!

4 个答案:

答案 0 :(得分:4)

Findbugs已经对hashCode进行了一些检查:(另见http://findbugs.sourceforge.net/bugDescriptions.html

  • HE_EQUALS_NO_HASHCODE
  • HE_EQUALS_USE_HASHCODE
  • HE_HASHCODE_NO_EQUALS
  • HE_HASHCODE_USE_OBJECT_EQUALS
  • HE_INHERITS_EQUALS_USE_HASHCODE(这可能对您的案件有用)

如果这些对你来说还不够,那么它们可能是创建自定义探测器的良好起点。

更新。检测器的源代码可以在https://code.google.com/p/findbugs/source/browse/findbugs/src/java/edu/umd/cs/findbugs/和该repo的其他包中找到。

答案 1 :(得分:1)

你可以反过来试试:

向所有(类似实体)类添加hashCode()方法。使用findbugs可以轻松验证该方法的非阻抗。实现看起来像:

@Override
public int hashCode() { 
 throw new UnsupportedOperationException("hashcode() not supported.");
}

通过这种方式,您可以确保没有Object.hashCode()" fallback" - 该类不会用于HashMaps,HashTables,HashSets或任何其他将调用hashCode()的情况。

答案 2 :(得分:-1)

我认为这将非常困难(如果它甚至可能)。但我还有两件事你可以尝试找到类应该覆盖hashCode()的地方:

  1. 至少Netbeans提示"覆盖等于但不是hashCode"这可能会有所帮助。

  2. Object.hashCode()上放置一个断点并运行一个或多或少具有代表性的测试集。

答案 3 :(得分:-1)

如果你想找到所有没有实现getHashCode()的类,你不能只使用简单的text-search / grep方法吗?

在项目中搜索所有带有.java结尾的文件,这些文件不包含字符串" public int getHashCode",为此编写脚本会相当容易。你可以,例如只需使用一个简单的搜索工具查找包含该文本的所有java文件,并从所有.java文件列表中减去此列表。结果列表将包含所有.java文件,这些文件不会覆盖getHashCode()