实现Comparable,compareTo名称冲突:“具有相同的擦除,但没有一个覆盖另一个”


问题内容

我想要一个带有Real的compareTo方法(一个用于处理任意大而精确的实数的类[好吧,只要它现在的长度小于2 ^
31])和一个带有一个对象,但是Java不允许我这样做,而且我还没有足够的经验来知道为什么。

我只是试图修改该类以实现Comparable,并且在下面得到了这些错误消息。我不是很明白错误消息的含义,但是我知道这与我试图为类制作的每个方法提供所有不同方法签名的灵活性的可怕方式有关,我可以修复它可以通过删除compareTo(Object
other)方法来实现,但是理想情况下,我希望保留它。因此,我真正要问的是:是否有一种方法可以使这些错误消息消失而又不删除compareTo(Object
other)方法,这些错误的确切含义是什么?

另外,我知道已经有一些内置的Java类,例如BigInteger,以及类似的东西,这些都是我试图使用该类的目的,但我这样做是出于乐趣/满意度,以便与Project
Euler(https:// projecteuler.net/)。

Jake@Jake-PC /cygdrive/c/Users/Jake/Documents/Java/Mathematics
$ javac Real.java
Real.java:377: error: name clash: compareTo(Real) in Real overrides a method whose erasure is the same as another method, yet neither overrides the other
  public int compareTo(Real other)
             ^
  first method:  compareTo(Object) in Real
  second method: compareTo(T) in Comparable
  where T is a type-variable:
    T extends Object declared in interface Comparable
Real.java:440: error: name clash: compareTo(Object) in Real and compareTo(T) in Comparable have the same erasure, yet neither overrides the other
  public int compareTo(Object other)
             ^
  where T is a type-variable:
    T extends Object declared in interface Comparable
2 errors

这些是compareTo方法:

  @Override
  public int compareTo(Real other)
  {
    // Logic.
  }
  public int compareTo(char givenValue) 
  { return compareTo(new Real(givenValue)); }
  public int compareTo(char[] givenValue) 
  { return compareTo(new Real(givenValue)); }
  public int compareTo(char[] givenValue, int offset, int count) 
  { return compareTo(new Real(givenValue, offset, count)); }
  public int compareTo(double givenValue) 
  { return compareTo(new Real(givenValue)); }
  public int compareTo(float givenValue) 
  { return compareTo(new Real(givenValue)); }
  public int compareTo(int givenValue) 
  { return compareTo(new Real(givenValue)); }
  public int compareTo(long givenValue) 
  { return compareTo(new Real(givenValue)); }
  public int compareTo(Object other) 
  { return compareTo(new Real(other.toString())); }

以及构造函数,以防万一您需要它们:

  public Real(String givenValue)
  {
    // Logic.
  }
  public Real(char givenValue) 
  { this(String.valueOf(givenValue)); }
  public Real(char[] givenValue) 
  { this(String.valueOf(givenValue)); }
  public Real(char[] givenValue, int offset, int count) 
  { this(String.valueOf(givenValue, offset, count)); }
  public Real(double givenValue) 
  { this(String.valueOf(givenValue)); }
  public Real(float givenValue) 
  { this(String.valueOf(givenValue)); }
  public Real(int givenValue) 
  { this(String.valueOf(givenValue)); }
  public Real(long givenValue) 
  { this(String.valueOf(givenValue)); }
  public Real(Object other) 
  { this(other.toString()); }

问题答案:

令人反感的方法是:

@Override
public int compareTo(Real other) { ... }

public int compareTo(Object other) { ... }

这些方法具有相同的
Erase

,这意味着一旦编译器剥离了通用类型信息,就不再有在运行时区分它们的方法。

您的选择是消除compareTo(Object other)重载,或者Real实施Comparable<Object>

由于看起来您所有compareTo重载的实现都只是实例化一个新的Real并将其传递给compareTo(Real),所以我建议删除它们并将转换留给调用者:

Real real = ...;
Object compared = ...;

Real comparedAsReal = new Real(compared);
int result = real.compareTo(comparedAsReal);