继承的方法Object.clone()无法隐藏公共抽象方法

时间:2011-07-26 22:27:01

标签: java generics compiler-construction

所以,我有一些狂野的,疯狂的代码,这使得编译器在我的脸上吐了几个小时以下错误:

The inherited method Object.clone() cannot hide the public abstract method in IOrderable<T>

罪魁祸首类如下(错误出现在通用的T中):

public class MyInterval<T extends Xpto & Successorable<T>> implements Cloneable {
    public MyInterval<T> clone(){
        MyInterval<T> it = null;
        try {
            it = (MyInterval<T>) super.clone();
            it.max = it.max.clone();
            it.min = (T) it.min.clone();
        } catch (CloneNotSupportedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return it;
    }
}

public interface Xpto {}

public interface Successorable<Y> extends IOrderable<Y> {
    Y suc();    
}   

interface IOrderable<J> extends Rankable<J>, Cloneable {
    boolean greaterEq(J e);
    J clone();
}

public interface Rankable<P> {
    int rank(P e);
}

是的,他们似乎有点随意。它们仅用于在我正在进行的编译器/ java_byte_code_instrumentation类项目中测试一些奇怪的东西。如何在保持逻辑完整的同时完成这项工作?

由于

5 个答案:

答案 0 :(得分:7)

我遇到了相同的编译错误,据我所知,这是交集类型(多重绑定泛型类型)规范中的边缘情况,并且没有可能的解决方案。

一个小测试用例:

public interface InterfaceA {
    public Object clone();
}

public interface InterfaceB {}

public class ClassA<T extends InterfaceA> {} // ok

public class ClassB<T extends InterfaceA & InterfaceB> {} //not ok

您不能拥有包含任何接口的交集类型,这些接口包含其签名与基类上的非公共方法匹配的任何方法(在本例中为隐式Object)。但这并非特定于Object或clone:

public abstract class Base {
    protected abstract void m();
}

public interface Interface {
    public void m();
}

public class Class<T extends Base & Interface> {} // not ok

Here's the relevant Oracle bug,标记为“不是缺陷”。

Here's the relevant Eclipse bug,其中编译器被修改为产生相同的错误以匹配javac。这似乎是Indigo 3.7的一个变化,这解释了为什么有些人可以复制而有些人无法复制。

答案 1 :(得分:3)

我认为this tutorial解释了问题,你应该能够找出解决方案。问题是当一个类型参数有几个边界时。

以下代码会复制错误。

interface Xpto
{
}

interface Xable < T >
{
    T clone ( ) ;
}

class MyStuff < S extends Xpto & Xable < S > >
{
}

但是下面的代码基本相同,但没有编译器错误。

interface Xpto
{
}

interface Xable < T > extends Xpto
{
    T clone ( ) ;
}

class MyStuff < S extends Xable < S > >
{
}

答案 2 :(得分:0)

我解决了将clone实现为public

的问题

答案 3 :(得分:0)

我也遇到了这个错误,但是我觉得我有点不同......

以下代码可以正常工作:(它嵌套在另一个类中,因此接口不需要公共方法)。

interface A{}
class B{
    class C extends B implements A{ }
}

将非公共方法添加到接口A中时会出现问题,并在B类中以非公开方式实现。

interface A{
    void doeet();

}

class B{
    void doeet(){};
    class C extends B implements A{
    }
}

查看您的代码,似乎是类似的,因为接口中的某些方法尚未声明为公共。

答案 4 :(得分:0)

我有同样的错误。

在我的情况下,我忘记了必须在实现方法的前面使用public关键字,因为包含它的类实现了定义它的接口。