Verstaendnisfrage Generics

sirbender

Top Contributor
Hi,

ich spiele gerade mit Generics rum und frage mich was die beste Loesung ist. Folgender Code funktioniert nicht:

Java:
public class Generic<T> {
    
    public static void main(String[] args) {
        String str = "hello";
        Generic<? extends String> g = new Generic<>(str.getClass());
        g.doStuff(str);
    }

    private Class<T> type;

    public Generic(Class<T> type) {
        this.type = type;
    }

    private void doStuff(T arg) {
        System.out.println(arg);
    }
    
}

Dieser Code funktioniert, aber new Generic(str.getClass()); hat gar keine Typ-Information und die IDE beschwert sich auch. Zwar nur eine Warnung, aber ich frage mich ob es besser geht?

Java:
public class Generic<T> {
    
    public static void main(String[] args) {
        String str = "hello";
        Generic<String> g = new Generic(str.getClass());
        g.doStuff(str);
    }

    private Class<T> type;

    public Generic(Class<T> type) {
        this.type = type;
    }

    private void doStuff(T arg) {
        System.out.println(arg);
    }
    
}
 

httpdigest

Top Contributor
Aktuell benutzt du das type Feld ja gar nicht. Deswegen:
Java:
public class Generic<T> {
    public static void main(String[] args) {
        String str = "hello";
        Generic<String> g = new Generic<>();
        g.doStuff(str);
    }
    private void doStuff(T arg) {
        System.out.println(arg);
    }
}
 
K

kneitzel

Gast
Wie wäre es mit so einer Lösung:
Code:
public class Generic<T> {
    
    public static void main(String[] args) {
        String str = "hello";
        Generic<String> g = new Generic<>(String.class);
        g.doStuff(str);
    }

    private Class<T> type;

    public Generic(Class<T> type) {
        this.type = type;
    }

    private void doStuff(T arg) {
        System.out.println(arg);
    }
}
 

httpdigest

Top Contributor
Oder mit der class-aus-empty-varargs Methode:
Java:
public class Generic<T> {
    public static void main(String[] args) {
        String str = "hello";
        Generic<String> g = new Generic<>();
        g.doStuff(str);
    }

    private Class<T> type;

    @SuppressWarnings("unchecked")
    public Generic(T... __dummy) {
        this.type = (Class<T>) __dummy.getClass().getComponentType();
    }

    private void doStuff(T arg) {
        System.out.println(arg);
    }
}
 

sirbender

Top Contributor
Wie wäre es mit so einer Lösung:
Code:
public class Generic<T> {
   
    public static void main(String[] args) {
        String str = "hello";
        Generic<String> g = new Generic<>(String.class);
        g.doStuff(str);
    }

    private Class<T> type;

    public Generic(Class<T> type) {
        this.type = type;
    }

    private void doStuff(T arg) {
        System.out.println(arg);
    }
}

Ich wollte ungern die Klasse explizit angeben, da dies zu Fehlern fuehren kann. Bei meinem echten Beispiel handelt es sich um eine Serialisierungsklasse die ein Objekt speichern und auch wieder laden soll. Ich will direkt das Objekt nutzen koennen um festzulegen fuer welche Objekttypen diese Klasse "funktionieren" soll. Wenn ich die Klasse immer per Hand explizit eingtrage und nicht per object.getclass() hole, koennten Fehler passieren.

Wundert mich schon, warum das nicht geht.
 

sirbender

Top Contributor
Oder mit der class-aus-empty-varargs Methode:
Java:
public class Generic<T> {
    public static void main(String[] args) {
        String str = "hello";
        Generic<String> g = new Generic<>();
        g.doStuff(str);
    }

    private Class<T> type;

    @SuppressWarnings("unchecked")
    public Generic(T... __dummy) {
        this.type = (Class<T>) __dummy.getClass().getComponentType();
    }

    private void doStuff(T arg) {
        System.out.println(arg);
    }
}

Geht natuerlich. Interessanter Hack. Nur leider auch irgendwie sehr seltsam. Hat type ueberhaupt einen Wert wenn man den Konstruktor ohne Argument aufruft?
 

mrBrown

Super-Moderator
Mitarbeiter
Ich wollte ungern die Klasse explizit angeben, da dies zu Fehlern fuehren kann. Bei meinem echten Beispiel handelt es sich um eine Serialisierungsklasse die ein Objekt speichern und auch wieder laden soll. Ich will direkt das Objekt nutzen koennen um festzulegen fuer welche Objekttypen diese Klasse "funktionieren" soll. Wenn ich die Klasse immer per Hand explizit eingtrage und nicht per object.getclass() hole, koennten Fehler passieren.

Wundert mich schon, warum das nicht geht.
in der Deklaration des Typs hast du die Klasse auch per Hand angegeben ;)

Ob das geht, hängt vom konkreten Fall ab, an so einem „einfachen“ Beispiel ist das schwierig zu beurteilen
 

sirbender

Top Contributor
in der Deklaration des Typs hast du die Klasse auch per Hand angegeben ;)

Ob das geht, hängt vom konkreten Fall ab, an so einem „einfachen“ Beispiel ist das schwierig zu beurteilen

Meinst du String str = "hello"; ?

War ja nur ein Beispiel. Normalerweise haette ich das Objekt schon und wuerde es nicht erstellen sondern nur nutzen.
 
K

kneitzel

Gast
Aber um das Objekt nutzen zu können wirst Du das doch in irgend einer Variable haben. Also musst Du da doch irgend etwas von dem Objekt wissen. Aber dann wäre es halt Object statt String. Und wenn Du es als "CoolSuperClass" hast, dann ist es halt CoolSuperClass.

Im Augenblick verstehe ich nicht ganz Dein Problem.
 

mrBrown

Super-Moderator
Mitarbeiter
Nimm statt String andere Typen, zB Number und Integer, vielleicht wird's damit klarer:

Java:
Number n = Integer.valueOf(42);
Generic<Number> g = new Generic<>(n.getClass());

EDIT: muss natürlich valueOf und nicht of heißen...
 
Zuletzt bearbeitet:

sirbender

Top Contributor
Nimm statt String andere Typen, zB Number und Integer, vielleicht wird's damit klarer:

Java:
Number n = Integer.valueOf(42);
Generic<Number> g = new Generic<>(n.getClass());

EDIT: muss natürlich valueOf und nicht of heißen...

Nicht wirklich :)
Klar ist Number und Integer nicht wirklich "kompatibel" in allen Bereichen. Da wuerde es mich nicht wundern, dass es ein Problem gibt.
Ich wunder mich halt warum Interger.class als Argument anderst ist als n.getClass(). Das Objekt sollte immer Integer.class zurueckliefern ob es jetzt in einer Number-Variable steckt oder nicht. Das Problem ist, dass n.getClass() halt nicht Class<Integer> zurueckliefert sondern Class<? extends Integer>. Warum eigentlich?
Mir ist nicht bewusst warum der Compiler hier nicht schlauer sein kann, vor allem wenn ich z.B. sowas schreibe:
Generic<Integer> g = new Generic<>(new Integer(42).getClass());
Das ist nun doch wirklich eindeutig.
 

mrBrown

Super-Moderator
Mitarbeiter
Ich wunder mich halt warum Interger.class als Argument anderst ist als n.getClass(). Das Objekt sollte immer Integer.class zurueckliefern ob es jetzt in einer Number-Variable steckt oder nicht. Das Problem ist, dass n.getClass() halt nicht Class<Integer> zurueckliefert sondern Class<? extends Integer>. Warum eigentlich?

Generics werden zur Compilezeit ausgewertet - und zur Compilezeit ist nur bekannt, das n vom Number ist.
n.getClass() kann also nicht Class<Integer> ergeben, weil das zur Compilezeit noch nicht feststeht - zur Compilezeit steht nur fest, dass es ein Subtyp von Number (oder Number) ist, also Class<? extends Number>.



Mir ist nicht bewusst warum der Compiler hier nicht schlauer sein kann, vor allem wenn ich z.B. sowas schreibe:
Generic<Integer> g = new Generic<>(new Integer(42).getClass());
Das ist nun doch wirklich eindeutig.
getClass gibt halt immer Class<? extends X> zurück, da Sonderregelungen für ein paar Spezialfälle einzuführen dürfte nicht unbedingt zielführend sein.

Vor allem da man das ja gleichwertig ersetzen kann mit Generic<Integer> g = new Generic<>(Integer.class);
 

mrBrown

Super-Moderator
Mitarbeiter
Weil getClass eben einen Subtyp des statischen Typs zurückgibt, und nicht den statischen Typ.

Beispiel steht doch oben :)
Generics werden zur Compilezeit ausgewertet - und zur Compilezeit ist nur bekannt, das n vom Number ist.
n.getClass() kann also nicht Class<Integer> ergeben, weil das zur Compilezeit noch nicht feststeht - zur Compilezeit steht nur fest, dass es ein Subtyp von Number (oder Number) ist, also Class<? extends Number>.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Verstaendnisfrage Instanzierung? Allgemeine Java-Themen 8
J Best Practice Generics mit Enum Allgemeine Java-Themen 3
H Kombination Interface und Abstrakte Klasse bei Generics Allgemeine Java-Themen 3
Zeppi Cast Object in Generics Allgemeine Java-Themen 4
P Generics und Arrays Allgemeine Java-Themen 6
M Generics / Typen Allgemeine Java-Themen 1
Kirby.exe InsertionSort mit Generics Allgemeine Java-Themen 33
Kirby.exe Vererbung bei Generics Allgemeine Java-Themen 7
H Klarnamen etc... (von Wie Generics lernen?) Allgemeine Java-Themen 26
D Wie Generics lernen? Allgemeine Java-Themen 26
L Compiler-Fehler Generics beim Anhängen von Predicates Allgemeine Java-Themen 1
W Vererbung Generics - mal wieder die verhaßte Rückwärtskompatibilität Allgemeine Java-Themen 2
W Generics + Vererbung Allgemeine Java-Themen 47
I Methoden Generics-Methode Allgemeine Java-Themen 3
D Mit Generics arbeiten - Übungsaufgabe Allgemeine Java-Themen 3
K Factory Pattern: Mit Generics umgehen Allgemeine Java-Themen 6
G Generics Allgemeine Java-Themen 31
perlenfischer1984 Liste mit generics zurück liefern Allgemeine Java-Themen 8
Hacer Generics & Collections Allgemeine Java-Themen 8
Neumi5694 Interface Generics für Enum-Filterung verwenden Allgemeine Java-Themen 5
H Collector Generics Problem (incl. Stream & Lambda) Allgemeine Java-Themen 4
C Gemeinsame Oberklasse zweier Generics Allgemeine Java-Themen 10
erdmann Datentypen Methodendeklaration mit Generics Allgemeine Java-Themen 2
Z Datentypen Verschachtelte Generics Allgemeine Java-Themen 1
Neumi5694 Datentypen Generics Allgemeine Java-Themen 5
S Mit Generics Klasse erstellen die selbst T erweitert..? Allgemeine Java-Themen 4
Tarrew Generics - Type erasure Allgemeine Java-Themen 5
N Problem mit Generics und Interface Allgemeine Java-Themen 4
H Generics als Parameter Allgemeine Java-Themen 1
kaoZ Generics und Vererbung Allgemeine Java-Themen 3
A Datentypen Generics: Wie am besten auf Typparameter zugreifen Allgemeine Java-Themen 2
C Generics Objekt in ArrayList Allgemeine Java-Themen 2
vandread Kleine Generics Aufgabe aus einer Prüfung... wie ist das gemeint? Allgemeine Java-Themen 6
G Generics sind zu streng - oder ich zu naiv? Allgemeine Java-Themen 3
G Verschachtelte Generics Allgemeine Java-Themen 2
O Generics Allgemeine Java-Themen 42
M Problem mit Generics Allgemeine Java-Themen 10
M Generics (bounded wildcards statt Interface Bezeichnern) -- Sinn oder Unsinn? Allgemeine Java-Themen 2
darekkay Generics: Wildcard und Object Allgemeine Java-Themen 5
H Collections Generics und Reflection Allgemeine Java-Themen 6
F Google Guice + Generics + Vererbung Allgemeine Java-Themen 5
H Problem mit Java Generics Allgemeine Java-Themen 6
J Generics: Typparameter als Klasse zurückliefern Allgemeine Java-Themen 4
H Generics Allgemeine Java-Themen 5
P Probleme mit Generics Allgemeine Java-Themen 5
B Generics und primitve arrays Allgemeine Java-Themen 6
M Generics Allgemeine Java-Themen 11
1 Collections Generics, internes Verhalten Allgemeine Java-Themen 16
T Warnungsfreie Verwendung von Generics Allgemeine Java-Themen 11
M Probleme mit Generics Allgemeine Java-Themen 5
D Java Generics Allgemeine Java-Themen 8
2 Generics: bounded wildcards Allgemeine Java-Themen 4
J Generics / vermeiden von downcasts Allgemeine Java-Themen 2
2 Generics oder nicht? Allgemeine Java-Themen 8
E Problem mit Generics und Comparable Allgemeine Java-Themen 16
W Erweitern einer Klasse mit Generics Allgemeine Java-Themen 8
H Generics für Methode Allgemeine Java-Themen 14
N Überladen mit Hilfe von Generics Allgemeine Java-Themen 3
S Generics: Fuer Set<T> ein T-Klassenobjekt erhalten? Allgemeine Java-Themen 3
Q Der innere Typ von Generics? Allgemeine Java-Themen 3
N Generics-NullpointerException Allgemeine Java-Themen 7
2 Generics - Typ Allgemeine Java-Themen 12
P Generics Problem Allgemeine Java-Themen 10
S Type safety Warnings beim casten von Generics Allgemeine Java-Themen 6
N Generics Allgemeine Java-Themen 3
V Frage zu Generics Allgemeine Java-Themen 2
S java generics klassen deklaration Allgemeine Java-Themen 7
B hashtable für unterschiedliche Typen - mit Generics Allgemeine Java-Themen 8
E Generics Allgemeine Java-Themen 3
MQue Generics Allgemeine Java-Themen 4
R Problem mit Reflection und Generics Allgemeine Java-Themen 3
C Klassen, die aufeinander verweisen (mit Generics) Allgemeine Java-Themen 16
G Generics - W.card unter Nutzung von Annotationsklasse? Allgemeine Java-Themen 6
G sortieren von generics Allgemeine Java-Themen 10
G Generics in Map. Type of value abhängig vom key Allgemeine Java-Themen 3
A Generics Verständnisfrage Allgemeine Java-Themen 7
Z Generics funzt nicht? Allgemeine Java-Themen 2
T Generics Allgemeine Java-Themen 18
G ComboBox: Nur eine Art Klasse zulassen (Generics) Allgemeine Java-Themen 3
J Generics Expertenwissen? Allgemeine Java-Themen 5
S Generics-Problem Allgemeine Java-Themen 3
T Generics und Wil-dcards Allgemeine Java-Themen 8
Q Typen von Generics & Casten Allgemeine Java-Themen 3
S Generics Allgemeine Java-Themen 2
R Problem mit Generics Allgemeine Java-Themen 2
G Trotz Generics Cast-Fehler! Allgemeine Java-Themen 5
T TreeMap durch Comparator mit Generics sortieren Allgemeine Java-Themen 9
T Generics und instanceof Allgemeine Java-Themen 10
T Generics und Exceptions Allgemeine Java-Themen 6
M Beliebig viele Typen bei Generics Allgemeine Java-Themen 3
G Reflection objekt mit generics erzeugen Allgemeine Java-Themen 5
S Singleton Pattern mit Generics Allgemeine Java-Themen 4
G Generics und Comparable Allgemeine Java-Themen 11
H Generics Problem Allgemeine Java-Themen 3
F Generics: spricht etwas dagegen raw types zu verwenden? Allgemeine Java-Themen 31
M Generics - besser programmieren, Warnung umgehen Allgemeine Java-Themen 4
E Java, UML, Generics Allgemeine Java-Themen 6
P Array von Vectoren + Generics Allgemeine Java-Themen 6
M ArrayList erweitern - generics Allgemeine Java-Themen 4
E Generics -> UML Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben