Унаследованный метод Object.clone () не может скрыть открытый абстрактный метод - PullRequest
13 голосов
/ 27 июля 2011

Итак, у меня есть немного дикого, безумного кода, который заставляет компилятор плюнуть мне в лицо на несколько часов из-за следующей ошибки:

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 ]

7 голосов
/ 31 августа 2011

Я столкнулся с той же ошибкой компиляции, и, насколько я могу судить, это крайний случай в спецификации для типов пересечений (универсальные типы с множественными связями), и решение невозможно.

Небольшой тестовый кейс:

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). Однако это не относится к объекту или клону:

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

public interface Interface {
    public void m();
}

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

Вот соответствующая ошибка Oracle , помеченная как «Не дефект».

Вот соответствующая ошибка Eclipse , в которой компилятор был изменен для получения той же ошибки, чтобы соответствовать javac. Похоже, это было изменением для Индиго 3.7, что объясняет, почему некоторые люди могли размножаться, а другие - нет.

3 голосов
/ 27 июля 2011

Я думаю, этот урок объясняет проблему, и вы сможете найти решение. Проблема в том, что параметр типа имеет несколько границ.

Код ниже повторяет ошибку.

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 > >
{
}
0 голосов
/ 12 августа 2018

У меня была такая же ошибка.

В моем случае я забыл ключевое слово public перед методом, который должен был быть реализован, поскольку класс, содержащий его, реализовал интерфейс, определяющий его.

0 голосов
/ 04 мая 2012

Я тоже получил эту ошибку, однако я думаю, что пришел к ней немного по-другому ....

следующий код работает нормально: (он вложен в другой класс, поэтому интерфейсу не нужноесть открытые методы).

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{
    }
}

ПросмотрВаш код кажется похожим в том, что некоторые методы в интерфейсах не были объявлены общедоступными.

0 голосов
/ 28 марта 2012

Я решаю эту проблему, реализуя клон как public

...