Java: Wie kann diese generische Methode überschrieben werden?

8
%Vor%

Wenn ich folgende Methode zum Überschreiben verwende

%Vor%

Ich bekomme folgenden Fehler:

%Vor%

Wie kann ich das lösen? Ich brauche die Methode nicht, um generisch zu sein, und eigentlich sollte es auch nicht sein. Was ich meine ist das

%Vor%

Funktioniert nicht, da die Methode ein neues Objekt von MyType erstellen kann, das nicht mit List "kompatibel" ist.

Wie kann ich das schaffen?

BEARBEITEN:

Zur Klarstellung. Ich versuche, die verschiedenen save () - Methoden von Spring-Daten SimpleJpaRepository (die von QuerydslJpaRepository erweitert wird) zu überschreiben

Klassendefinitionen:

%Vor%

Und das (von Spring Data)

%Vor%

EDIT 2:

Die Methode ruft save (MyType-Entity) für jedes Element auf und diese Methode enthält folgende Logik:

  1. entity hat ein Feld, das eindeutig ist
  2. hole diesen Feldwert und überprüfe, ob eine Entität mit diesem Wert bereits existiert
  3. Wenn ja, verwenden Sie diese Entität (Aufruf von entityManager.merge) - & gt; funktioniert nicht returns MyType nicht S
  4. wenn nein, erstellen Sie eine neue - & gt; Hier wird ein neues Objekt erstellt. Funktioniert nicht mit dem generischen Typ

Für 4. Ich kann einfach id = null setzen und das übergebene Objekt verwenden. Das funktioniert nicht für 3.

Ich bin sehr verwirrt, warum diese Methode diese Signatur hat. Es macht es für mich unbrauchbar und ich verstehe nicht, warum ich eine Unterklasse von T mit Ts DAO speichern würde. die Speichermethoden sind die einzigen mit. Alle anderen benutzen nur T. Ich könnte einfach nach S umwandeln, um es kompilieren zu lassen, aber das scheint auch hässlich ... da jeder andere Typ als T zu einer Ausnahme führen würde.

    
beginner_ 24.10.2012, 12:40
quelle

5 Antworten

0

Meine Lösung bestand darin, dies nicht zu überschreiben, sondern eine Serviceklasse zu erstellen, die die benötigte Logik ausführt und das Repository unberührt lässt.

    
beginner_ 10.12.2012, 09:28
quelle
8

Damit eine Methode eine andere überschreiben kann, muss sie auf mindestens alle gültigen Parameter der überschriebenen Methode angewendet werden. Ihre Basismethode ist generisch public <S extends T> List<S> save(Iterable<S> entities) . Es akzeptiert also jeden Typ S , der T erweitert. Ihre Überschreibung ist jedoch restriktiver, da sie nur Sammlungen von MyType akzeptiert, daher ist es keine gültige Überschreibung.

Wenn Sie Ihre Basisklasse mit T definiert und die Methode nur T akzeptiert und die abgeleitete Klasse T auf MyType gesperrt hat, sollten Sie OK sein.

Um eine bessere Antwort zu geben, müssen wir die Klassendeklarationen für die zwei Klassen sehen. Ich würde Folgendes vorschlagen:

%Vor%

BEARBEITEN:

Wenn Sie keine Kontrolle über die Basisklasse haben (was Sie nicht zu tun scheint), stecken Sie fest mit der public <S extends MyType> List<S> save(Iterable<S> structures) Signatur. Dies liegt daran, dass die überschriebene Methode generalisiert ist und die überschreibende Methode also auch

sein muss     
John B 24.10.2012 12:56
quelle
3

Hängt davon ab, wie Sie die folgenden Funktionen definiert haben

%Vor%     
Walter Laan 24.10.2012 13:05
quelle
2

Hier ist ein Beispiel, das kompiliert und zeigt, wie man es benutzt:

%Vor%

Die Klasse A definiert die Methode mit der ursprünglichen Signatur. Die Klasse B implementiert sie und wählt List<Integer> für den Typparameter T . Und schließlich verwendet die Klasse C diese Methode mit einem Iterable Hure. Der generische Typ ist eine Unterklasse von List<Integer> .

    
Andreas_D 24.10.2012 13:03
quelle
1

Seit

%Vor%

ist angegeben, Ihre Überschreibung muss für

gelten %Vor%

und Ihre Implementierung muss beachten, dass S ein echter Untertyp von MyType sein könnte.

Ihre Vorgehensweise

%Vor%

ist keine korrekte Überschreibung:

  • seit Java & gt; = 1.5 erlaubt kovariante Rückgabetypen und List<MyType> ist ein Subtyp von List<S extends MyType> , das ist ok, aber
  • Java erlaubt nur invariante Parametertypen, aber Iterable<MyType> ist ein Subtyp von Iterable<S extends MyType> , daher Ihre Compiler-Fehlermeldung.
DaveFar 24.10.2012 13:00
quelle