2015-10-20 24 views
5

Rzućmy tej klasy strukturę:Generics problem: clone() próbuje przypisać słabsze uprawnienia dostępu

public interface TypeIdentifiable {} 

public interface TypeCloneable extends Cloneable { 
    public Object clone() throws CloneNotSupportedException; 
} 

public class Foo implements TypeCloneable, TypeIdentifiable { 

    @Override 
    public Object clone() throws CloneNotSupportedException { 
     // ... 
     return null; 
    } 
} 

public abstract class AbstractClass<T extends TypeCloneable & TypeIdentifiable> { 

    public void foo(T element) throws Exception { 
     TypeCloneable cloned = (TypeCloneable) element.clone(); 
     System.out.println(cloned); 
    } 
} 

mam ten błąd kompilacji (chociaż IDE, Intellij w moim przypadku, nie jest w stanie pokazać błąd podczas kodowanie)

Error:(4, 37) java: clone() in java.lang.Object cannot implement clone() in foo.TypeCloneable attempting to assign weaker access privileges; was public 

wiem, że kompilator próbuje wywołać metodę z Objectclone() zamiast TypeCloneable, ale nie rozumiem dlaczego. Próbowałem również casting do TypeCloneable (I suposed kompilator byłoby wiedzieć, które wywołanie metody clone() w tym przypadku, ale ten sam problem).

public void foo(T element) throws Exception { 
     TypeCloneable typeCloneable = (TypeCloneable) element; 
     TypeCloneable cloned = (TypeCloneable) typeCloneable.clone(); 
    } 

Jestem nieco zdezorientowany ... Czy mogę coś tutaj zrobić, aby zmusić klonowanie klonów() z TypeCloneable?

Dzięki za HELLP

+1

Jeśli Rozumiem JLS poprawnie, należy skompilować . Myślę, że to błąd. http://stackoverflow.com/questions/33023332/why-doesnt-this-java-program-compile –

+1

Tak, tak ... to wygląda na błąd. Nie znalazłem tego pytania. Dzięki! – troig

Odpowiedz

2

Działa to dla mnie (jestem zgadywania to jest problem z typem składni Górne granice Rodzaj &):

interface TypeIdentifiable {} 

interface TypeCloneable extends Cloneable { 
    public Object clone() throws CloneNotSupportedException; 
} 

class Foo implements TypeCloneable, TypeIdentifiable { 

    @Override 
    public Object clone() throws CloneNotSupportedException { 
     // ... 
     return null; 
    } 
} 

interface TypeCloneableAndIndetifiable extends TypeCloneable, TypeIdentifiable { 

} 
abstract class AbstractClass<T extends TypeCloneableAndIndetifiable> { 

    public void foo(T element) throws Exception { 
     TypeCloneable cloned = (TypeCloneable) element.clone(); 
     System.out.println(cloned); 
    } 
} 
+0

Dzięki za odpowiedź @ WillShackleford. Tak, jeśli zawijam oba interfejsy w jeden, jak mówisz, działa. Problem polega na tym, że zarówno TypeCloneable jak i TypeIdentifiable są starszym kodem. Czy myślisz, że może to być błąd związany ze składnią górnego słowa & Type? – troig

+0

Nie jestem pewien. Pomyślałbym, że zadziała, jak go użyłeś, zanim zobaczyłem to pytanie. – WillShackleford

+0

Jak wskazuje @Paul Boddington w komentarzu, wygląda na to, że jest to błąd. Może mógłbyś edytować swoją odpowiedź, dodając to. W każdym razie, akceptuję twoją odpowiedź na twoją sugestię o zawijaniu dwóch interfejsów w jeden. Dzięki – troig