实现可比性,比较名称冲突:“具有相同的擦除,但两者都不能覆盖另一个”

2022-09-04 02:27:07

我希望有一个比较To方法,它采用Real(一个用于处理任意大而精确的实数的类[好吧,只要它目前长度小于2 ^ 31])和一个采用Object的compareTo方法,但是Java不让我,我没有足够的经验来知道为什么。

我只是尝试修改类以实现可比性,我在下面收到了这些错误消息。我真的不明白错误消息是什么意思,但我知道这与我试图为我所做的每个方法的所有不同方法签名的可怕方式有关,并且我可以通过删除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()); }

答案 1

违规的方法是:

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

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

这些方法具有相同的擦除,这意味着一旦编译器剥离了泛型类型信息,就不再有办法在运行时区分它们。

您的选项是删除重载,或实现 。compareTo(Object other)RealComparable<Object>

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

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

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

答案 2

由于您希望能够将对象与 进行比较,因此可以只将 替换为 。这与javadoc一致,javadoc说.RealObjectimplements Comparable<Real>implements Comparable<Object>Comparable<T><T> the type of objects that this object may be compared to

然后,您只需要将当前代码更改为:

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

推荐