IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Récupérer le type parametrant un paramètre générique


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut Récupérer le type parametrant un paramètre générique
    Soit les classes suivantes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public class Base<T> {
     
      T id;
      public T getId() {
        return id;
      }
      public void setId(T id) {
        this.id = id;
      }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Generique<U,T extends Base<U>> {
     
      Base<U> laBase;
     
      public void setLaBase(Base<U> laBase) {
        this.laBase = laBase;
      }
     
      public U getBaseId(){
        return laBase.getId();
      }
     
    }
    et deux classes: Machin extends Base<MonObjet> et MachinTruc extends Generique<MonObject,Machin>U et T sont redondant, toute l'information sur U est déjà présente dans T. Je voudrais donc pouvoir faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public class MachinTruc extends Generique<Machin>
    mais je n'arrive pas à trouver comment déclarer Generique pour demander au compilateur d'extraire U à partir de T :/ Je ne sais même pas si c'est possible...



    Pour la petite histoire, j'ai déjà en réalité une classe
    Generique<T extends BaseString> mais je me retrouve sur un cas où il faudrait typer avec un BaseInteger, donc je voudrait refactorer la déclaration vers Base<> pour accepter plus large, mais si possible en n'ajoutant pas un paramètre générique car cela rendrait l'aval incompilable sans modif. Et des sous classes de Generique, on en a des dixaines dans différents projets . L'alternative c'est d'introduire une super classe qui reprends tout le code actuel:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class SuperGenerique<U,T extends Base<U>> {
     
      Base<U> laBase;
     
      public void setLaBase(Base<U> laBase) {
        this.laBase = laBase;
      }
     
      public U getBaseId(){
        return laBase.getId();
      }
     
    }
    et changer generique en

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public class Generique<T extends BaseString> extends SuperGenerique<String,T>
    Mais je voudrait éviter de créer cette classe en carton qui ne sert qu'à éviter le refactoring en aval

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    A quoi sert "T" dans ta classe "Generique" ? Tu ne l'utilise pas dans ton code.

    Autant faire directement ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Generique<U> {
     
      Base<U> laBase;
     
      public void setLaBase(Base<U> laBase) {
        this.laBase = laBase;
      }
     
      public U getBaseId(){
        return laBase.getId();
      }
     
    }

    a++

  3. #3
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    D'abord c'est une exemple, la classe réelle est bien plus complexe utilise le T dans ses interaction. Voilà un meilleur example

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Generique<U,T extends Base<U>> {
     
      T laBase;
     
      public void setLaBaseT laBase) {
        this.laBase = laBase;
      }
     
      public U getBaseId(){
        return laBase.getId();
      }
     
    }
    Le code existant est fait grosso modo


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Generique<T extends BaseString> {
     
      T laBase;
     
      public void setLaBaseT laBase) {
        this.laBase = laBase;
      }
     
      public String getBaseId(){
        return laBase.getId();
      }
     
    }
    Et je dois le refactorer en un truc genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Generique<T extends Base<?????>> {
     
      T laBase;
     
      public void setLaBaseT laBase) {
        this.laBase = laBase;
      }
     
      public ????? getBaseId(){
        return laBase.getId();
      }
     
    }
    en ayant les appelant qui travaillaient avec une sous classe de BaseString toujours capables de faire


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String id = laSousClassDeGenerique.getBaseId();

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Il faudrait voir le code exact, mais as-tu réellement besoin de paramétrer le type de Base ?

    [edit] Soit tu as besoin de paramétrer U et T et dans ce cas là tu dois obligatoirement utiliser deux types paramétrés.
    Soit tu as uniquement besoin de paramétrer U en utilisant un Base<U> sans plus de détail...


    a++

  5. #5
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    Tu veux faire ça ? :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public class Generique<T extends Base<U>, U> {
     
    	  T laBase;
     
    	  public void setLaBase(T laBase) {
    	    this.laBase = laBase;
    	  }
     
    	  public U getBaseId(){
    	    return laBase.getId();
    	  }
    	}
    Tu passes ton objet T qui étend Base<U> et tu peux récupérer U...


    Et tu l'appelles comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    public static void main(String[] args){
    		  Base<String> bString = new Base<String>(){
     
    			@Override
    			public String getId() {
    				return "String";
    			}
     
    		  };
     
    		  Generique<Base<String>, String> myGen = new Generique<>();
    		  myGen.setLaBase(bString);
    		  myGen.getBaseId();
    	  }

    Et oui, dans la déclaration, il FAUT les deux types paramétrés... Mais il y a des astuces pour n'avoir besoin que d'un seul...

  6. #6
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    La méthode pour n'en déclarer qu'un seul :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public interface GenericInterface<T extends Base<U>, U> {
     
    	public void setLaBase(T laBase);
     
    	public U getBaseId();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    public class Generique<U> implements GenericInterface<Base<U>, U> {
     
    	Base<U> laBase;
     
    	@Override
    	public void setLaBase(Base<U> laBase) {
    		this.laBase = laBase;
     
    	}
     
    	@Override
    	public U getBaseId() {
    		return laBase.getId();
    	}
     
    	public static void main(String[] args) {
    		Base<String> bString = new Base<String>() {
     
    			@Override
    			public String getId() {
    				return "String";
    			}
     
    		};
     
    		Generique<String> myGen = new Generique<>();
    		myGen.setLaBase(bString);
    		String myStr = myGen.getBaseId();
    	}
     
    }

Discussions similaires

  1. [JAX-WS] Récupérer du XML dans un paramètre de type String
    Par verbose dans le forum Services Web
    Réponses: 0
    Dernier message: 01/07/2014, 17h19
  2. avoir le type du paramétre générique par réflexion
    Par al3alwa dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 22/01/2010, 13h36
  3. Passage d'un type procédure en paramètre par défaut
    Par Floverdoz dans le forum Langage
    Réponses: 1
    Dernier message: 22/07/2005, 17h48
  4. Récupérer le type de démarrage d'un service
    Par Nathan dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 09/04/2004, 15h07
  5. Type String* en paramètre...
    Par Invité dans le forum MFC
    Réponses: 4
    Dernier message: 24/02/2004, 19h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo