Generics-Problem: Class, Class<?>, Class<Object>

sirbender

Top Contributor
Moderne IDE's (und deren Compiler) aber auch der Java-Compiler tadeln es wenn man parameterisierte Typen parameterlos nutzt. Pflichtbewusst setzt man dann <?> oder <Object> damit diese Warnung weggeht.

Leider fuehrt das zu allerlei Problemen und Inkompatibilitaeren - wobei mich wundert, dass es diese ueberhaupt gibt. Eigentlich sollte Class, Class<?> und Class<Object> doch relativ gleichbedeutend sein, oder?

Ich habe mal ein Codebeispiel angehaengt, das zeigt, was ich meine. Was ist der beste Weg? Vor allem kommen Funktionen wie a(), b() und c() oft aus externen Libraries, wodurch man dann eingeschraenkt ist was man uebergibt.

Java:
import java.util.LinkedHashSet;

public class GenericsProblem {
    
    public static void main(String[] args) {
        LinkedHashSet<Class> s1 = new LinkedHashSet<>();
        a(s1);
        b(s1); // compile error
        c(s1); // compile error
        
        LinkedHashSet<Class<Object>> s2 = new LinkedHashSet<>();
        a(s2); // compile error
        b(s2);
        c(s2); // compile error
        
        LinkedHashSet<Class<?>> s3 = new LinkedHashSet<>();
        a(s3); // compile error
        b(s3); // compile error
        c(s3);
    }

    static void a(Iterable<Class> classes) {}
    static void b(Iterable<Class<Object>> classes) {}
    static void c(Iterable<Class<?>> classes) {}
}
 

Barista

Top Contributor
Java:
package java_forum.generics;

import java.util.LinkedHashSet;

public class GenericsProblem {

     public static void main(String[] args) {
            LinkedHashSet<Class<Object>> s1 = new LinkedHashSet<>();
            a(s1);
            b(s1);
            c(s1); // compile error: The method b(Iterable<Class<Object>>) in the type GenericsProblem is not applicable for the arguments (LinkedHashSet<Class<?>>)

            
            LinkedHashSet<Class<Object>> s2 = new LinkedHashSet<>();
            a(s2);
            b(s2);
            c(s2); // compile error: The method c(Iterable<Class<?>>) in the type GenericsProblem is not applicable for the arguments (LinkedHashSet<Class<Object>>)
            
            LinkedHashSet<Class<?>> s3 = new LinkedHashSet<>();
            a(s3);
            b(s3); // compile error: The method c(Iterable<Class<?>>) in the type GenericsProblem is not applicable for the arguments (LinkedHashSet<Class<Object>>)
            c(s3);
        }

        static void a(Iterable<? extends Class> classes) {} // geändert gegenüber original post
        static void b(Iterable<Class<Object>> classes) {}
        static void c(Iterable<Class<?>> classes) {}
        
}

Ich habe die Methode a mal so angepasst, dass nur Elemente aus dem Iterable gelesen werden.
Dies ist auch das normale Verhalten.
Es bleiben aber noch Compiler-Fehler übrig.

Den Typ des LinkedHashSet habe ich auch angepasst, um keine Raw-Typ zu haben.
 

httpdigest

Top Contributor
Es gibt keinen "besten Weg". Welches Typargument du bei Methodeparameterdeklarationen und Variablendeklarationen verwenden musst, hängt davon ab, wie die Instanz des parametrisierten Typs in der Methode genutzt wird.
Es gibt eine Eselsbrücke, die sich "P.E.C.S." nennt: "Producer Extends, Consumer Super".
Diese sagt soviel aus wie: Wenn der parametrisierte (Container)-Typ lesend verwendet wird, also du auf diesem Methoden aufrufst, deren Rückgabetyp die Typvariable beinhaltet (heißt: Der parametrisierte Typ ist ein "Producer" - er produziert Daten) dann verwende `<? extends Something>`.
Wenn der parametrisierte Typ als Konsument verwendet wird, also du Methoden auf ihm aufrufst, deren Parametertypen Typvariablen sind, dann verwende `<? super Something>`.
Es macht bei näherem Nachdenken tatsächlich alles Sinn und ich empfehle dir dringend, dir die Generics Tutorials von Oracle und von Angelika Langer anzuschauen!

Und: Class, Class<?> und Class<Object> beschreiben allesamt unterschiedliche Typen. Die Tutorials erklären, welche und warum.
 

Barista

Top Contributor
Java:
package java_forum.generics;

import java.util.LinkedHashSet;

public class GenericsProblem {

     public static void main(String[] args) {
       
            // Typ-Argument Class ist Raw, das untergeordnete Typ-Argument fehlt
            LinkedHashSet<Class> s1 = new LinkedHashSet<>(); // warning: Class is a raw type. References to generic type Class<T> should be parameterized
            a(s1);
            b(s1); // compile error: Typ mit Raw-Typ-Argument passt nicht in Typ mit Typ-Argument mit untergeordneten Typ-Argument
            c(s1); // compile error: Typ mit Raw-Typ-Argument passt nicht in Typ mit Typ-Argument mit untergeordneten Typ-Argument
            d(s1); // compile error: Typ mit Raw-Typ-Argument passt nicht in Typ mit Typ-Argument mit untergeordneten Typ-Argument
           
            // Typ-Argument Class hat ein invariantes untergeordnetes Typ-Argument Object
            LinkedHashSet<Class<Object>> s2 = new LinkedHashSet<>();
            a(s2); // compile error: Typ mit Typ-Argument mit untergeordneten Typ-Argument passt nicht in Typ mit Raw-Typ-Argument
            b(s2);
            c(s2); // compile error: Typ mit Class-Typ-Argument passt nicht in Typ mit ?-Joker-Typ-Argument
            d(s2); // so geht es

            // Typ-Argument Class hat ein untergeordnetes Platzhalter-Typargument, welches keinen Zugriff auf die Elemente erlaubt (also nur Zugriff auf Behälter-Methoden wie size)
            LinkedHashSet<Class<?>> s3 = new LinkedHashSet<>();
            a(s3); // compile error: Typ mit Typ-Argument mit untergeordneten Typ-Argument passt nicht in Typ mit Raw-Typ-Argument
            b(s3); // compile error: Joker ? bedeutet, dass kein Zugriff auf Elemenz erlaubt
            c(s3);
            d(s3);
        }

        static void a(Iterable<Class> classes) {} // warning: untergeordneter Raw-Typ
        static void b(Iterable<Class<Object>> classes) {}
        static void c(Iterable<Class<?>> classes) {}
        static void d(Iterable<? extends Class<?>> classes) {}
}

Ich habe noch mal geändert.
Ich hoffe, die Kommentare erklären die einzelnen Fälle.
Unten gibts noch die Methode d, die manche Aufrufe komoilierbar macht.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Compiler-Fehler Generics Problem Java Basics - Anfänger-Themen 2
T Polymorphie Generics-Problem Java Basics - Anfänger-Themen 2
L Datentypen Problem mit Generics und null Java Basics - Anfänger-Themen 6
W Interface Problem mit Generics Java Basics - Anfänger-Themen 2
A Problem mit Generics Java Basics - Anfänger-Themen 4
M kleines generics problem Java Basics - Anfänger-Themen 15
P Generics Problem Java Basics - Anfänger-Themen 5
T von ArrayList erben - Problem mit Generics Java Basics - Anfänger-Themen 2
H Generics machen mich verrückt Java Basics - Anfänger-Themen 8
John_Sace Homogene Realisierung von Generics in Java ? Java Basics - Anfänger-Themen 19
MarvinsDepression Datentypen Generics: Erste Berührungen Java Basics - Anfänger-Themen 6
M Generics Vererbung Listen Java Basics - Anfänger-Themen 2
Cassy3 Generics - CompareTo Java Basics - Anfänger-Themen 21
T Collections Sind Subklassen-Objekte in Listen mit Generics erlaubt? Java Basics - Anfänger-Themen 16
districon Generics implementieren Java Basics - Anfänger-Themen 2
CptK Überprüfen ob übergebenes Objekt zu Generics passt Java Basics - Anfänger-Themen 2
CptK Generics: Klassen die Interface implementieren, aber selbst nicht das Interface sind Java Basics - Anfänger-Themen 8
B Hilfe bei Generics Java Basics - Anfänger-Themen 11
G Generics Compilerfehler Java Basics - Anfänger-Themen 6
G Generics Methoden Java Basics - Anfänger-Themen 7
G Generics Java Basics - Anfänger-Themen 3
L Generics Tripel Java Basics - Anfänger-Themen 26
W Fragen zu Generics Java Basics - Anfänger-Themen 14
S Hilfe. Generics und BiFunctions Java Basics - Anfänger-Themen 10
X Wie Generics richtig benutzen ? Java Basics - Anfänger-Themen 5
S Allgemeine Frage über Generics und Vererbungen Java Basics - Anfänger-Themen 5
I Java Generics factory method Java Basics - Anfänger-Themen 2
M Verständnisfrage zu Generics Java Basics - Anfänger-Themen 7
I Generics und Comparable Java Basics - Anfänger-Themen 14
G Generics mit ? und Diamantoperator Java Basics - Anfänger-Themen 4
G Generics: Wildcard ? Java Basics - Anfänger-Themen 12
D Generics methode Java Basics - Anfänger-Themen 2
I Frage zu Generics und Wildcards Java Basics - Anfänger-Themen 2
N Generics und Casting eines Objekts Java Basics - Anfänger-Themen 1
A Generics Java Basics - Anfänger-Themen 6
A Vererbung/Interfaces/Generics Java Basics - Anfänger-Themen 12
W Generics - Typ zurückbekommen Java Basics - Anfänger-Themen 4
Dimax Erste Schritte Generics von Profis leicht erklärt Java Basics - Anfänger-Themen 7
C Warum funktioniert 'instanceof' bei generics nicht? Java Basics - Anfänger-Themen 4
J Collections Generics: Typ wird nicht erkannt Java Basics - Anfänger-Themen 7
D Generics ArrayList: Bug im Quellcode Java Basics - Anfänger-Themen 14
C Generics Java Basics - Anfänger-Themen 8
M Generics getter und setter Methoden Java Basics - Anfänger-Themen 4
T Generics in Java... Java Basics - Anfänger-Themen 9
J Generics Java Basics - Anfänger-Themen 3
J Generics Datentypen vergleichen Java Basics - Anfänger-Themen 16
V Generics / eigene Liste Java Basics - Anfänger-Themen 4
O Generics - Implementierung Java Basics - Anfänger-Themen 7
Shizmo Frage zu Generics Java Basics - Anfänger-Themen 3
F Multiple Generics Java Basics - Anfänger-Themen 10
G Datentypen verschiedene Objekte in eine ArrayList, Generics Java Basics - Anfänger-Themen 2
H Typsicherheit/Generics Java Basics - Anfänger-Themen 1
U Java generics funktioniert nicht Java Basics - Anfänger-Themen 0
Tarrew Generics: Erste gemeinse Oberklasse als Rückgabewert Java Basics - Anfänger-Themen 1
N Generics Vererbung Wildcard Interface Java Basics - Anfänger-Themen 8
S Generics und Comparable Interface Java Basics - Anfänger-Themen 5
A Generics Java Basics - Anfänger-Themen 4
M Frage zu Generics in Klassen, Abstrakten Klassen und Interfaces Java Basics - Anfänger-Themen 5
K Interface Generics, Interfaces und Listen - ich bin verwirrt. Java Basics - Anfänger-Themen 7
K Generics bei Klassen- und Interfacedeklarationen Java Basics - Anfänger-Themen 3
D toArray und Generics Java Basics - Anfänger-Themen 2
D Zwei Generics beim Überladen von Methoden Java Basics - Anfänger-Themen 3
C Erste Schritte Filter für Generics oder ähnliches Java Basics - Anfänger-Themen 2
M Frage zu Generics-Deklaration Java Basics - Anfänger-Themen 5
S Frage zu Collection-Generics in Subklassen Java Basics - Anfänger-Themen 6
J Java Generics - Frage zu Types Java Basics - Anfänger-Themen 2
M <T> Generics Java Basics - Anfänger-Themen 7
B Interface Generics: prüfen ob Interface deklariert wird Java Basics - Anfänger-Themen 18
B Hilfe beim Verständnis zu Generics Java Basics - Anfänger-Themen 7
J Array Generics Java Basics - Anfänger-Themen 3
J Generics casten Java Basics - Anfänger-Themen 14
J Generics wildcard Java Basics - Anfänger-Themen 6
E Listen und Generics Java Basics - Anfänger-Themen 9
X Generics Java Basics - Anfänger-Themen 6
M Datei einlesen mit generics? Java Basics - Anfänger-Themen 9
D Warum sind Generics mit Vorsicht zu genießen? Java Basics - Anfänger-Themen 6
M OOP Mit Generics auf Methoden zugreifen? Java Basics - Anfänger-Themen 10
S Generics Java Basics - Anfänger-Themen 4
G Generics kein Zugriff auf getter eines Objekts Java Basics - Anfänger-Themen 4
E Klassen java.util.ArrayList<E> als Generics Java Basics - Anfänger-Themen 16
M OOP Generics und Wildcards Java Basics - Anfänger-Themen 3
D Generics - Warnmeldungen Java Basics - Anfänger-Themen 2
M Polymorphie generics einsteigerprobleme Java Basics - Anfänger-Themen 3
D Vererbung Generics und Vererbung Java Basics - Anfänger-Themen 8
C Generics Array Java Basics - Anfänger-Themen 43
D Fehler mit generics Java Basics - Anfänger-Themen 10
S Generics - CaseInsensitiveMap selber schreiben? Java Basics - Anfänger-Themen 5
K Datentypen Generics Java Basics - Anfänger-Themen 3
P Comparable und Generics Java Basics - Anfänger-Themen 6
I Generics (Subtypen) Java Basics - Anfänger-Themen 17
N Typeinschränkung bei Generics Java Basics - Anfänger-Themen 13
C Generics und Cast Java Basics - Anfänger-Themen 5
H Generics werden in -source 1.2 nicht unterstützt Java Basics - Anfänger-Themen 16
M Datentypen Generics: Exacten Typ ermitteln Java Basics - Anfänger-Themen 6
N Generics und Interfaces Java Basics - Anfänger-Themen 5
S Generics und "generische Feldzuweisungen" Java Basics - Anfänger-Themen 5
lumo Java Generics Java Basics - Anfänger-Themen 19
M verlinkte Liste mit generics Java Basics - Anfänger-Themen 7
capgeti Datentypen Static methoden aus Superklasse mit Generics definieren? Java Basics - Anfänger-Themen 9
S Generics und Typerkennung Java Basics - Anfänger-Themen 7

Ähnliche Java Themen

Neue Themen


Oben