有谁知道为什么 java.lang.Number
不实施Comparable
?这意味着你无法排序Number
s的Collections.sort
这对我来说有点陌生.
发布讨论更新:
感谢所有有用的回复.我最后对这个话题进行了更多的研究.
java.lang.Number未实现Comparable的原因的最简单解释源于可变性问题.
对于位的检讨,java.lang.Number
是抽象的超类型的AtomicInteger
,AtomicLong
,BigDecimal
,BigInteger
,Byte
,Double
,Float
,Integer
,Long
和Short
.在那个列表上,AtomicInteger
并AtomicLong
没有实现Comparable
.
四处搜索,我发现Comparable
在可变类型上实现这不是一个好习惯,因为对象在比较期间或之后可能会发生变化,因此比较结果无用.这两个AtomicLong
和AtomicInteger
是可变的.API设计者已经预见到没有Number
实现,Comparable
因为它会限制未来子类型的实现.确实,AtomicLong
并且AtomicInteger
在java.lang.Number
最初实现之后很久就被添加到Java 1.5中.
除了可变性之外,这里也可能有其他考虑因素.一compareTo
实施Number
就必须促进所有的数字值BigDecimal
,因为它是能够容纳所有的Number
子类型.这种促销在数学和表现方面的含义对我来说有点不清楚,但我的直觉发现了解决方案.
值得一提的是以下表达式:
new Long(10).equals(new Integer(10))
永远是false
,这往往会使每个人在某个时刻绊倒.因此,您不仅无法比较任意Number
s,而且甚至无法确定它们是否相等.
此外,对于真实的原始类型(float
,double
),确定两个值是否相等是棘手的,并且必须在可接受的误差范围内完成.尝试以下代码:
double d1 = 1.0d; double d2 = 0.0d; for (int i=0; i<10; i++) { d2 += 0.1d; } System.out.println(d2 - d1);
你会留下一些小小的差异.
所以回到制作的问题Number
Comparable
.你会如何实现它?使用类似的东西是doubleValue()
不可靠的.记住Number
子类型是:
Byte
;
Short
;
Integer
;
Long
;
AtomicInteger
;
AtomicLong
;
Float
;
Double
;
BigInteger
; 和
BigDecimal
.
你能编写一个compareTo()
不会转换成一系列if instanceof语句的可靠方法吗? Number
实例只有六种可用的方法:
byteValue()
;
shortValue()
;
intValue()
;
longValue()
;
floatValue()
; 和
doubleValue()
.
所以我猜Sun做出的(合理的)决定Number
只是Comparable
针对自己的例子.
有关答案,请参阅Java bugparade bug 4414323.您还可以从comp.lang.java.programmer中找到讨论
引用Sun对2001年错误报告的回应:
所有"数字"都不具有可比性; 可比较假定数字的总排序是可能的.浮点数甚至都不是这样; NaN(不是数字)既不小于,也不大于,也不等于任何浮点值,甚至本身.{Float,Double} .compare强加一个不同于浮点"<"和"="运算符排序的总排序.此外,如当前实现的那样,Number的子类仅与同一类的其他实例相当.还有其他情况,例如复数,其中不存在标准总排序,尽管可以定义一个.简而言之,Number的子类是否具有可比性应留作该子类的决定.