首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实现可比较的compareTo名称冲突:“具有相同的擦除,但两者都不会覆盖另一个”

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

Stack Overflow用户
提问于 2013-06-15 04:35:25
回答 3查看 18.7K关注 0票数 14

我希望有一个接受Real (一个类,可以很好地处理任意大而精确的实数,只要它现在的长度小于2^31 )和一个接受对象的compareTo方法的compareTo方法,但是Java不允许我这样做,我也没有足够的经验知道为什么。

我只是试着修改这个类来实现可比较的,我得到了下面的错误消息。我真的不明白错误消息是什么意思,但我知道这与我试图给类提供一些灵活性的可怕方式有关,我为每个方法创建了所有不同的方法签名,我可以通过删除compareTo(Object other)方法来修复它,但理想情况下我希望保留它。所以我真正想问的是:有没有一种方法可以在不删除compareTo(Object other)方法的情况下消除这些错误消息,以及这些错误的确切含义是什么?

此外,我知道已经有一些内置的Java类,比如BigInteger和类似的东西,用于我试图使用这个类的目的,但我这样做是为了好玩/满足于使用Project Euler (https://projecteuler.net/)。

代码语言:javascript
复制
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方法:

代码语言:javascript
复制
  @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())); }

和构造器,以防你需要它们:

代码语言:javascript
复制
  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()); }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-06-15 04:58:01

有问题的方法有:

代码语言:javascript
复制
@Override
public int compareTo(Real other) { ... }

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

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

您的选择要么是移除compareTo(Object other)重载,要么是让Real实现Comparable<Object>

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

代码语言:javascript
复制
Real real = ...;
Object compared = ...;

Real comparedAsReal = new Real(compared);
int result = real.compareTo(comparedAsReal);
票数 14
EN

Stack Overflow用户

发布于 2013-06-15 05:00:41

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

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

代码语言:javascript
复制
// 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())); }
票数 3
EN

Stack Overflow用户

发布于 2013-06-15 04:59:21

这是泛型类型擦除的副作用。

您正在实现一个泛型接口,但这是它的唯一方法,一旦泛型类型被擦除,它将变成compareTo(Object),因此它与您自己的compareTo(Object)冲突。

下面是要重现的最小代码:

代码语言:javascript
复制
class Real implements Comparable<Real>
{
    public int compareTo(Object o)
    {
        return 0;
    }

    @Override
    public int compareTo(Real o)
    {
        return 0;
    }       
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17116845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档