1

我读过在实现 equals 时考虑别名是一个坏主意。
一个例子equalsFile.
我想知道为什么这是一个坏主意?仅仅因为实现更难正确吗?
如果FileAFileB引用同一个文件但具有不同的路径名,为什么它们不相等?

4

3 回答 3

2

我认为File实际上是一个相当棘手的例子。

可以期望 Java 运行时知道硬链接吗?已安装的NFS共享上的硬链接?

我认为“不”是对最后一个问题的公平答案,在这种情况下File.equals()只能在尽力而为的基础上工作。

于 2012-05-03T07:41:17.723 回答
2

对于指向同一个实际文件的别名文件名,让 equals() 返回 true 是一个坏主意,因为它违反了关于相等行为的常见假设。

考虑以下示例:

  • 即使它们现在引用相同的底层文件,这也可能在未来发生变化(例如,由于文件系统的变化使一个路径无效)。您希望现在平等的事物在未来保持平等(当然,除非您明确地改变它们)。
  • 如果您转换文件(例如通过向上一个目录),那么结果也将不相等。这里违反的假设是您希望将相同的操作应用于两个相同的事物以产生相同的结果。

因此我们可以看到,考虑到别名会为两个所谓的“相等”对象产生一些意想不到的行为。当人们做出不正确的假设时,这可能会在未来引起奇怪和微妙的错误。

第二个但也相关的问题是,考虑别名可能会增加相当大的实现复杂性和性能开销。您通常希望equals()非常高效,因为它可能会经常被调用:如果它被迫对操作系统进行 IO 调用以确定文件别名,那么这种情况不太可能发生。

在这种情况下,我将实现一个完全不同的函数来测试指向相同的物理文件 -refersToSameFile或类似的东西。这允许您为操作使用更具描述性的名称,并避免弄乱对相等行为的期望。

于 2012-05-03T07:48:02.663 回答
1

确切地说,他们为什么不能平等?或者他们为什么会这样做?

这只是口味和/或要求的问题。在某些情况下,您需要在两个别名之间进行多样化,在其他情况下,只有目标文件很重要。决定并不容易,因此做出决定至少要确保 java 版本之间的兼容性。

此外,在某些文件系统上,无法检测您是在处理链接还是实际文件(至少不是使用默认的 jre 工具)。

于 2012-05-03T07:46:55.613 回答