first answer 完全正确地解释了为什么会出现 ClassCastException - Comparable 接口是通用接口,只能用于相同具体类型的对象。
可能还有其他方法可以解决您的问题:
基元及其对象包装器
如果您确定所有数字都是基元 (int, long, float, double) 或表示基元的类的对象 (Integer, Long, Float, Double),那么您可以只使用普通的比较运算符,例如等同于n1.compareTo(n2);
int b = n1 > n2 ? 1 : (n1 < n2 ? -1 : 0);
Number 的子类
如果您确定所有变量都属于扩展 Number 的类,即 AtomicInteger, AtomicLong, BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short,则可以使用以下命令:
private int compareNumbers(Number n1, Number n2)
{
Double n2c = n2.doubleValue();
Double n1c = n1.doubleValue();
return n1c.compareTo(n2c);
}
public static void main (String[] args)
{
Integer n1 = new Integer(432);
Long n2 = new Long(40);
Double n3 = new Double(500.12);
System.out.println(compareNumbers(n1,n2));
}
编辑
针对与 OP 的评论讨论 - 我们注意到,如果比较两个超出 @ 范围的 BigDecimal 或 BigInteger 数字,使用 Double 作为 Number 比较的基类可能会产生虚假相等987654334@(因此 .doubleValue() 会根据需要返回 Double.POSITIVE_INFINITY 或 Double.NEGATIVE_INFINITY)
如果这是一个问题,compareNumbers() 可以更改如下:
private int compareNumbers(Number n1, Number n2)
{
BigDecimal n2c = new BigDecimal(n2.toString());
BigDecimal n1c = new BigDecimal(n1.toString());
return n1c.compareTo(n2c);
}
/编辑
实现Comparable,但不要扩展Number
如果您甚至无法确定您的变量是否扩展了 Number,并且您可能正在处理具有表示数字的类的变量,则实现 Comparable,但不扩展 Number,我相信您只能比较参数,如果他们属于同一类。在这种情况下,这应该可以工作,但我真的无法想象用例:
Comparable n1 = new WierdNonNumberExtendingInteger(432);
Comparable n2 = new WierdNonNumberExtendingLong(40);
Comparable n3 = new WierdNonNumberExtendingDouble(500.12);
Integer b = null;
if (n1.getClass().isInstance(n2))
{
b = n1.compareTo(n2);
}
else
{
System.err.println("Can't compare apples and oranges");
System.err.print("You tried to compare " + n1.getClass().getSimpleName());
System.err.print(" with " + n2.getClass().getSimpleName());
}
System.out.println(b);