2017-05-10 3 views
-1

Mein Verständnis über generische war, dass, wenn ich public void saveAll(Collection<? extends Object> stuff) { dann compile wird die "am häufigsten verwendete Art" des Eingabeparameters zu Collection<Object>. Jetzt, mit, dass ich unter Code schrieb die generischen Methoden für das Überschreiben, aber ich erhalte folgende Fehlermeldung in der übergeordneten Methode - Name clash: The method saveAll(Collection<? extends Object>) of type ChildWithGenericMethod has the same erasure as saveAll(Collection<Object>) of type ParentWithGenericMethod<T> but does not override itTyp löschen und überschreiben generische Methode

public class ParentWithGenericMethod { 
    public void saveAll(Collection<Object> stuff) { 

    } 
} 

public class ChildWithGenericMethod extends ParentWithGenericMethod{ 
    public void saveAll(Collection<? extends Object> stuff) { 

    } 
} 

Was ich wissen will, ist, dass nach Typ Löschung, wie diese Methoden aussehen würden, wie, ich dachte, sie würden wie public void saveAll(Collection stuff) { aussehen und daher sollte ich in der Lage sein, zu überschreiben, denn wenn ich Generika nicht verwende, dann kann ich wie folgt überschreiben.

Bitte beachten Sie, dass ich weiß, dass ich den Byte-Code nach der Kompilierung mit "javap" sehen kann, aber es sagt mir nicht, wie diese Methoden nach "type löschung" aussehen würden.


Update:
Diese Frage meiner Frage nicht beantworten, wenn nach Typ Löschung beiden Methoden werden public void saveAll(Collection stuff) { warum dann Unterklasse überschreiben Fehler bekommen, denn mit public void saveAll(Collection<Object> stuff) { es den zwingenden Regeln geht.

+2

"nach type löschen wie diese methoden aussehen würden" 'öffentliche void saveAll (Collection stuff)' –

+1

Was meinst du mit "am häufigsten Typ"? – user2357112

+0

@AndyTurner Warum bekomme ich dann diesen Fehler, dass es die Methode nicht überschreibt? – pjj

Antwort

0

Es lohnt sich, sich an die Laufzeit und den Kompilierungszeitversand zu erinnern.

Generika für eine Sekunde wegnehmen.

public class Parent { 
    public void saveAll(Object x) { 
    } 
} 

public class Child extends Parent { 
    public void saveAll(String x) { 
    } 
} 

public String x = "hello"; 
public Object y = new Integer(334); 
public Object z = "goodbye"; 

public Child c1 = new Child(); 

c1.saveAll(x); // invokes Child.saveAll 
c1.saveAll(y); // invokes Parent.saveAll 
c1.saveAll(z); // invokes Parent.saveAll even though z contains a String 

Jetzt setzen Generics zurück in die Geschichte.

public class Child<T extends Object> extends Parent { 
    public void saveAll(T x) { 
    } 
} 

Hier überspannt saveAll das saveAll des übergeordneten Objekts und überschreibt es nicht.

ersetzt T mit einem anoymous? ändert das nicht wirklich - der Compiler versucht, eine Methode zu erstellen, die die Methode des übergeordneten Elements überlädt, aber dann erkennt, dass sie nicht zum Kompilierungszeittyp senden kann.

[Bearbeiten, Lew Block-Kommentar auf dem Original sehen: der Compiler muss, ob das Kind Methode überschreibt, um entscheiden oder Überlastungen der Methode des Mutter vor Typ Löschung]

0

wenn nach Typ Löschung beiden Methoden öffentlich werden void saveAll (Collection stuff) {Warum wird die Unterklasse überschrieben, weil mit public void saveAll (Collection stuff) {die übergeordneten Regeln übergibt.

Das Problem (wieder Lew Blochs Kommentar sehen) ist, dass übergeordnete vor Typ Löschung bestimmt wird. Vor der Typlöschung haben die Eltern- und die Kindmethode unterschiedliche Signaturen. Daher erstellt der Compiler sie als überladene Methoden und nicht als Methoden, die überschrieben werden. Nach dem Löschen des Typs erkennt der Compiler, dass er in einem Bind ist, da er nun zwei Methoden mit der gleichen Signatur und keine Möglichkeit hat, zu versenden.

Verwandte Themen