为什么java.lang.Number不实现Compeable?

2022-08-31 07:40:54

有谁知道为什么不实现?这意味着你不能对s进行排序,这在我看来有点奇怪。java.lang.NumberComparableNumberCollections.sort

发布讨论更新:

感谢所有有用的回复。我最终对这个话题做了更多的研究

关于java.lang.Number为什么不实现Compeable的最简单解释植根于可变性问题。

稍加回顾一下,是 、、、、和 的抽象超类型。在该列表中,并且不实现 .java.lang.NumberAtomicIntegerAtomicLongBigDecimalBigIntegerByteDoubleFloatIntegerLongShortAtomicIntegerAtomicLongComparable

四处挖掘,我发现在可变类型上实现不是一个好的做法,因为在比较期间或之后对象可能会发生变化,从而使比较结果变得无用。两者都是可变的。API设计人员有先见之明,没有实现,因为它会限制未来子类型的实现。事实上,在Java 1.5中添加了很久之后才被最初实现。ComparableAtomicLongAtomicIntegerNumberComparableAtomicLongAtomicIntegerjava.lang.Number

除了可变性之外,这里可能还有其他考虑因素。中的实现必须将所有数值提升为,因为它能够容纳所有子类型。这种推广在数学和性能方面的含义对我来说有点不清楚,但我的直觉发现这个解决方案是笨拙的。compareToNumberBigDecimalNumber


答案 1

值得一提的是,以下表达式:

new Long(10).equals(new Integer(10))

总是,这往往会在某个时候绊倒每个人。因此,您不仅可以不比较任意的s,甚至无法确定它们是否相等。falseNumber

此外,对于实基元类型 (, ),确定两个值是否相等是很棘手的,必须在可接受的误差范围内完成。尝试如下代码:floatdouble

double d1 = 1.0d;
double d2 = 0.0d;
for (int i=0; i<10; i++) {
  d2 += 0.1d;
}
System.out.println(d2 - d1);

你会留下一些小的差异。

所以回到制作.您将如何实现它?使用类似的东西不会可靠地做到这一点。请记住,亚型是:NumberComparabledoubleValue()Number

  • Byte;
  • Short;
  • Integer;
  • Long;
  • AtomicInteger;
  • AtomicLong;
  • Float;
  • Double;
  • BigInteger;和
  • BigDecimal.

你能编写一个可靠的方法,不退化成一系列if实例语句吗? 实例只有六种方法可供它们使用:compareTo()Number

  • byteValue();
  • shortValue();
  • intValue();
  • longValue();
  • floatValue();和
  • doubleValue().

所以我猜Sun做出了(合理的)决定,s只针对他们自己的实例。NumberComparable


答案 2

有关答案,请参阅 Java bugparade bug 4414323。你也可以从comp.lang.java.programmer找到一个讨论。

引用太阳对2001年错误报告的回应:

所有“数字”都不具有可比性;可比较假设可以对数字进行总排序。对于浮点数来说,情况甚至并非如此。NaN(不是数字)既不小于,也不大于或等于任何浮点值,甚至本身。{Float, Double}.compare 施加的总排序不同于浮点“<”和“=”运算符的顺序。此外,按照当前实现,Number 的子类仅与同一类的其他实例相当。还有其他情况,如复数,其中不存在标准的总排序,尽管可以定义一个。简而言之,Number的子类是否具有可比性,应保留为该子类的决定。


推荐