tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
5
ZUGRIFFE
242
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    chickenwings chickenwings ist offline Mitglied Gold
    Registriert seit
    Nov 2005
    Beiträge
    213
    Hallo,

    das Thema Generics scheint doch komplizierter zu sein, als ich dachte.
    Habe folgendes Problem:

    ein Klasse:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    public class Attribute<T extends Object>
    {
        private String name;
        private Class<T> theClazz;
     
            public Attribute(String name, Class<T> clazz)
        {
            this.name = name;
            this.theClazz = clazz;
        }
     
            ....
    }

    Der Aufruf des Konstruktors funktioniert wunderbar, solange ich z.B. folgenden Aufruf mit nicht parameterisierten Generics (hier String) durchführe:
    Code :
    1
    
    public static final Attribute<String> myAttr = new Attribute<String>("enable", String.class);

    Ist das generische Object allerdings selbst parameterisiert:
    Code :
    1
    
    public static final Attribute<List<?>> listAttr = new Attribute<List<?>>("container", List.class);

    .. gibt es die Fehlermeldung, dass der entsprechende Konstruktor nicht defniert ist. Das ist auch klar, denn der Konstruktor erwartet nur eine Klasse eines beliebigen Typs.

    Wie kann man das erweitern, dass auch komplexere Konstrukte funktionieren?

    Grüsse,
    chickenwings
     

  2. #2
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist gerade online Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    Hi,
    ich habe mich auch vor kurzem erst mit Generics beschäftigt.
    Wieso machst du das denn auch doppelt in deinem Code. Es würde (aus meiner Sicht) auch reichen, wenn du nur ein GenericType entweder im Konstruktor übergibst oder eben in den <T>. Da du auf das T ja eh schon zugreifen kannst aus der Attribute-Klasse.
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    public class Attribute<T extends Object>
    {
        private String name;
     
        public Attribute(String name)
        {
            this.name = name;
        }
    }
    Ich kann mich allerdings auch täuschen.

    Gruß

    Fabio
     
    Bitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]

    Tutorials:
    Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
    JAnimationPanel - Animationen für Swing/AWT
    SWTRatingBar (Bewertungs-Composite) selbst programmieren
    ____________________________________________________________________________
    Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.

  3. #3
    chickenwings chickenwings ist offline Mitglied Gold
    Registriert seit
    Nov 2005
    Beiträge
    213
    Hallo,

    nein das geht so leider nicht. In den Parametern gebe ich ja lediglich den Typen vor, der als Parameter im Konstruktor erlaubt ist. Das ganze dient der Typsicherheit.
    Über einen Getter will ich ja mal an den Typen der Klasse (Variable clazz) herankommen und dafür dient mir generische Typ.

    Grüsse,
    chickenwings
     

  4. #4
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist gerade online Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    Achso ok.

    Wenn du es so machst:
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    public class Attribute<T extends Object>
    {
        private String name;
        private final Class<?> clazz;
     
        public Attribute(String name, Class<?> clazz)
        {
            this.name = name;
            this.clazz = clazz;
        }
        
        public Class<T> getGenericType() {
            return (Class<T>) clazz;
        }
    }
    Kannst du den Aufruf so machen, wie du es willst:
    Code java:
    1
    
    Attribute<List<?>> listAttr = new Attribute<List<?>>("container", List.class);

    Ich vermute mal, dass das daran liegt, dass du bei List.class keinen GenericType mit übergeben kannst. Deshalb kannst du da nur Attribute<List> schreiben. So würde es dann auch funktionieren.
    Dadurch das Class<?> im Konstruktor jetzt aber offen lässt, welche Typen übergeben werden können, kann jetzt List.class und List<?> geschrieben werden.

    Ich hoffe, dass das einigermaßen verständlich beschrieben ist von mir.

    Gruß

    Fabio
     
    Bitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]

    Tutorials:
    Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
    JAnimationPanel - Animationen für Swing/AWT
    SWTRatingBar (Bewertungs-Composite) selbst programmieren
    ____________________________________________________________________________
    Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.

  5. #5
    chickenwings chickenwings ist offline Mitglied Gold
    Registriert seit
    Nov 2005
    Beiträge
    213
    Hallo,

    , ja darauf bin ich auch schon gekommen. Problem hierbei ist nur, dass ich dann die Typsicherheit zwischen dem Generic und dem .class-Object des Parameters verliere. Und das soll ja gerade die Stärke des Konstrukts werden.

    Grüsse,
    chickenwings
     

  6. #6
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist gerade online Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    Ja klar, dass ist natürlich das Risiko dabei. Aber du kannst es ja wie in deinem Konstrukt mit dem Aufruf machen:
    Code java:
    1
    
    Attribute<List> listAttr = new Attribute<List>("container", List.class);
    Weil: List == List<?>...

    // EDIT
    Vielleicht ist es das was du suchst...
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    public class Attribute<T extends Object>
    {
        private String name;
        private T value;
        private final Class<? extends T> clazz;
     
        public Attribute(String name, Class<? extends T> clazz) {
            this.name = name;
            this.clazz = clazz;
        }
     
        public Class<T> getGenericType() {
            return (Class<T>) clazz;
        }
    }
    Wenn du das so machst, hast du deine Typsicherheit. Allerdings must du beim erzeugen des Objekts ein wenig casten. Zumindest bei der List.
    Code java:
    1
    2
    3
    
    Attribute<String> myAttr = new Attribute<String>("enable", String.class);
    Attribute<List<?>> listAttr = new Attribute<List<?>>("container", (Class<? extends List<?>>) List.class);
    Class<List<?>> genericType = listAttr.getGenericType();
    Geändert von Fabio Hellmann (13.01.12 um 15:05 Uhr) Grund: Noch eine Möglichkeit gefunden
     
    Bitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]

    Tutorials:
    Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
    JAnimationPanel - Animationen für Swing/AWT
    SWTRatingBar (Bewertungs-Composite) selbst programmieren
    ____________________________________________________________________________
    Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.

Ähnliche Themen

  1. Antworten: 4
    Letzter Beitrag: 12.01.12, 12:30
  2. Problem - evtl mit Generics lösbar
    Von acky im Forum Java
    Antworten: 9
    Letzter Beitrag: 14.02.11, 18:58
  3. Antworten: 1
    Letzter Beitrag: 10.04.08, 00:06
  4. Generics Problem
    Von Iam_Fiction im Forum Java
    Antworten: 3
    Letzter Beitrag: 13.01.08, 14:59
  5. Comparable + Generics Problem
    Von bl4ck29 im Forum Java
    Antworten: 2
    Letzter Beitrag: 28.06.05, 16:50