实现Comparable,compareTo名称冲突:“具有相同的擦除,但不会覆盖其他”

我想有一个compareTo方法,它接受一个Real(一个用于处理任意大而精确的实数的类[好吧,只要它的长度小于2 ^ 31])和compareTo方法一个对象,但Java不让我,我没有足够的经验知道为什么。

我只是尝试修改类来实现Comparable,我在下面收到了这些错误消息。 我真的不明白错误信息是什么意思,但我知道它与我可怕的方式有关,我试图给我的课程一些灵活性,为我制作的每一种方法提供所有不同的方法签名,我可以解决它通过删除compareTo(Object other)方法,但我最好保留它。 所以我真正要问的是:有没有办法让这些错误消息消失而不删除compareTo(Object other)方法,这些错误究竟是什么意思?

另外,我知道已经有一些像BigInteger这样的内置Java类以及我正在尝试使用这个类的东西,但我正在为了与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) { ... } 

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

您可以选择删除compareTo(Object other)重载,或者Real实现Comparable

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

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

由于您希望能够将Real对象与Object进行比较,因此您可以使用implements Comparable替换implements Comparable implements Comparable 。 这与Comparable javadoc一致,后者表示 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())); } 

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

您正在实现一个通用接口 ,Comparable,但这是它的独特方法,一旦擦除generics类型将变为compareTo(Object) ,因此它与您自己的compareTo(Object)冲突。

这是一个重现的最小代码:

 class Real implements Comparable { public int compareTo(Object o) { return 0; } @Override public int compareTo(Real o) { return 0; } }