Java:Comment faire pour remplacer cette méthode générique?
public <S extends T> List<S> save(Iterable<S> entities) {
//...
}
Si j'utilise la méthode suivante pour remplacer
@Override
public List<MyType> save(Iterable<MyType> structures) {
List<MyType> result = new ArrayList<>();
//...
return result;
}
J'obtiens l'erreur suivante:
method does not override or implement a method from a supertype
name clash: save(Iterable<MyType>) in MyTypeRepositoryImpl and <S>save(Iterable<S>) in SimpleJpaRepository have the same erasure, yet neither overrides the other
where S,T are type-variables:
S extends T declared in method <S>save(Iterable<S>)
T extends Object declared in class SimpleJpaRepository
Comment puis-je résoudre ce problème? Je n'ai pas besoin de la méthode générique et en fait, il ne devrait pas être. Ce que je veux dire, c'est que
@Override
public <S extends MyType> List<S> save(Iterable<S> structures) {
List<S> result = new ArrayList<>();
//...
return result;
}
Ne fonctionnera pas, car la méthode permet de créer un nouvel Objet de MyType qui n'est pas "compatible" à la Liste.
Comment puis-je faire ce travail?
EDIT:
Pour obtenir des éclaircissements. Je suis en train de remplacer les différents save() les méthodes de Printemps de données SimpleJpaRepository (qui est étendu par QuerydslJpaRepository)
Classe definitions:
public class MyTypeRepositoryImpl
extends QueryDslJpaRepository<MyType, Long>
implements MyTypeRepository
@NoRepositoryBean
public interface MyTypeRepository
extends JpaRepository<MyType, Long>,
QueryDslPredicateExecutor<MyType>
Et ce (à partir du Printemps de Données)
public class QueryDslJpaRepository<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID>
implements QueryDslPredicateExecutor<T>
EDIT 2:
Les appels à la méthode save(MyType entité) pour chaque élément et que la méthode contient logique suivante:
- entité a un champ qui est unique
- obtenir que les champs de la valeur et de vérifier si l'entité avec la valeur existe déjà
- si oui, utiliser cette entité (appel à l'entityManager.de fusion) -> ne fonctionne pas retourne MyType pas S
- si pas d'en créer un nouveau -> ici nouvel objet est créé. Ne fonctionne pas avec le type générique
Pour 4 personnes. Je peux juste set id = null et l'utilisation du passé dans l'objet. Cela ne fonctionne pas pour 3.
Donc je suis très perplexe pourquoi cette méthode a cette signature. Il le rend inutilisable pour moi et je ne comprends pas pourquoi je voudrais enregistrer une sous-classe de T en utilisant Ts DAO. les méthodes enregistrer sont les seuls avec . Tous les autres n'utilisent T. je pourrais les jeter à S de faire de la compilation, mais qui semble moche...comme n'importe quel autre type de T conduirait à une exception.
qu'entendez-vous par pas "compatible" à la Liste? Il ressemble à de l'original
<S extends T>
paramètre de la classe est faite pour pouvoir être utilisé en faisant quelque chose comme implements InterfaceName<MyType>
sans avoir à muck autour avec un sous-classementÀ partir des commentaires à d'autres réponses et le fait que vous êtes à l'extension d'une classe sur laquelle vous n'avez aucun contrôle, je crois que vous êtes contraint d'utiliser
public <S extends MyType> List<S> save(Iterable<S> structures)
. C'est parce que la méthode de remplacement est généricisés et donc la overridding méthode doit l'être également.OriginalL'auteur beginner_ | 2012-10-24
Vous devez vous connecter pour publier un commentaire.
Pour une méthode pour remplacer un autre, il doit s'appliquer au moins à tous les paramètres valides de la méthode de remplacement. Votre méthode de base est générique
public <S extends T> List<S> save(Iterable<S> entities)
. Donc, il acceptera tout typeS
qui s'étendT
. Cependant votre remplacement est plus restrictive car elle n'acceptera que des collections deMyType
, il n'est donc pas valide remplacer.Si vous avez eu votre classe de base définis avec
T
, et la méthode acceptéeT
, et la classe dérivée verrouilléT
àMyType
vous devriez être OK.Afin de donner une meilleure réponse, nous avons besoin de voir les déclarations de classe pour les deux classes. Je vous suggère les suivantes:
EDIT:
Si vous n'avez pas de contrôle sur la classe de base (dont il semble que vous n'avez pas), vous êtes coincé avec le
public <S extends MyType> List<S> save(Iterable<S> structures)
signature. C'est parce que la méthode de remplacement est généricisés et donc la overridding méthode doit également êtreOriginalL'auteur John B
Dépend de la façon dont vous avez défini les ouvrages suivants
OriginalL'auteur Walter Laan
Voici un exemple qui compile et qui montre comment l'utiliser:
Classe
A
définit la méthode avec la signature originale. classeB
la met en œuvre, et choisitList<Integer>
pour le paramètre de typeT
. Et enfin, la classeC
utilise cette méthode avec unIterable
pute de type générique est une sous-classe deList<Integer>
.Confus. Si une classe est utilisée pour
T
vous ne trouverez pas une classe pourS
ce qui rend la méthode tout à fait inutilisable (pour ce cas)Ne pas s'acquitter de S? Je suis confus pour l'instant. :O
Désolé. J'ai eu tort. Je voulais la classe à la finale mais il est une Entité, et ne peut pas être définitive.
OriginalL'auteur Andreas_D
Depuis
est donné, votre dérogation doit être pour
et votre mise en œuvre doit respecter que pourrait être un véritable sous-type de MyType.
Votre approche
n'est pas correcte, remplacer:
List<MyType>
est un sous-type deList<S extends MyType>
, c'est ok, maisIterable<MyType>
est un sous-type deIterable<S extends MyType>
, par conséquent, votre compilateur message d'erreur.IC, adopté ma réponse en conséquence.
OriginalL'auteur DaveFar
Ma solution a été de ne pas surcharger ce, à tous, mais de créer un service de classe qui ne les avait besoin de logique et de laisser référentiel intacte.
OriginalL'auteur beginner_