Problem mit Generic bei unmodifiableCollection

SimProtect

Aktives Mitglied
Hallo,

Ich habe momentan ein Problem und hoffe auf Eure Hilfe.

Eine bestimmte Klasse hat folgende Signatur und eine bestimmte problematische Methode, die ich hier mal mit angegeben habe.

Java:
public class CollectionClass<T, R extends Collection<T>> extends SomeAbstractClass<R> {

    @Override
    public R get() {
        return Collections.unmodifiableCollection(super.get());
    }

}

Bei diesem Versuch erhalte ich immer den Compilerfehler angezeigt:
Incompatible types. Required R but 'unmodifiableCollection' was inferred to Collection<T>: no instance(s) of type variable(s) T exist so that Collection<T> conforms to R

Kann mir bei diesem Problem jemand auf die Sprünge helfen? Kann ich das in Java gescheit lösen? Wenn ja, wie?

Hinterinformationen:
-> Diese Klasse "MUSS" eine unmodifiableCollection zurückgeben (so ist die Anforderung hierfür)
-> An der API der (für diesen Thread so bezeichneten) SomeAbstractClass kann ich nichts ändern. Über das get() gibt sie selbst ein Objekt vom Typ R zurück
-> Alle weiteren Operationen mit und auf der Collection im Rahmen dieser Klasse funktionieren tadellos. Ich kann lediglich keine Read-Only-Ausgabe der hinterlegten Collection herausgeben.

Für etwas Hilfe bzw. Erläuterung wäre ich sehr dankbar.
 

httpdigest

Top Contributor
Wozu brauchst du den `R` Typparameter? Wenn du kannst, schreibe es so um:
Java:
public class CollectionClass<T> extends SomeAbstractClass<Collection<T>> {
    @Override
    public Collection<T> get() {
        return Collections.unmodifiableCollection(super.get());
    }
}

Erläuterung, warum deine Lösung nicht funktioniert: Das Problem ist, dass das Typargument für den Typparameter `R` immer eine ganz ganz konkrete Collection<T> sein wird, und Collections.unmodifiableCollection() aber natürlich nicht exakt denselben Collectiontyp R zurückliefert, sondern eben "irgendein" Collection-Typ, der nur T als Elementtyp hat. Und das stört den Compiler und da hat er ja auch Recht. Denn der Vertrag deiner Klasse sagt ja: Gegeben eine ganz konkrete Collection-Klasse für R, dann gibt get() auch eine Instanz von genau diesem ganz konkreten Collectiontyp R zurück und nicht _irgendein_ Collectiontyp.
 

SimProtect

Aktives Mitglied
Danke für Deine Antwort. Das hatte ich mir aus dem Fehlertext bereits herausziehen können. :) (trotzdem vielen Dank für die Mühe und die nette Antwort. Zumal ich da natürlich auch ungeschickterweise nach gefragt habe :D )
Die Frage ist eher, ob ich das 'irgendwie' so umsetzen kann.

Als ursprüngliche Variante war die Klasse nur auf T getyped und hatte an SomeAbstractClass dann eben Collection<T> weitergegeben (genau, wie Du beschrieben hattest). Das "Problem" daran war, dass ich weiteren Ableitungen von CollectionClass dann "Unschönigkeiten" aufkommen. Nehmen wir einmal an, wir fügen eine weitere Implementierung konkret für Lists, Sets oder Maps hinzu.
Bei Getter bzw. Zugriffen auf die Felder entsprechender Oberklassen kann ich dann noch casten <- sollte kein Problem darstellen, da "ich ja weiß" (blödes Argument, ich weiß), was für ein Typ ich reingeben.
Ärgerlich wird es dann bei Settern, die natürlich weiterhin Collection<T> annehmen, obwohl ich das natürlich nicht möchte.
Klar, ich könnte jetzt anfangen, dort immer eine RuntimeException (damit nicht jeder Aufruf mit Exception umgehen muss) zu werfen, wenn ein falsches Objekt hereinkommt, aber das wäre nun auch unschön.
Wenn mir die API explizit erlaubt eine Collection reinzugeben, würde ich als aufruf (javadoc mal hin oder her) auch erwarten, dass ich auch genau das kann und mich nicht mehr um solche Feinheiten kümmern zu müssen.

Bei uns befinden sich die entsprechenden Klassen im Framework und sollten solche Unschönheiten den übrigen Entwicklerteams natürlich abnehmen bzw. es sollte möglichst komfortabel sein, das zu benutzen.
Vielleicht habe ich mich hier im Konzept auch schlicht und ergreifend mal wieder völlig verrannt und sehe die offensichtliche Lösung nicht mehr.

Unter anderen Umständen hätte ich diese CollectionClass aus der Veerbungshierarchie von SomeAbstractClass herausgelöst und über einen eigenen Strang verarbeitet, um ein derartiges Problem zu umgehen. Leider haben wir hier (momentan) keinen Zugriff auf die SomeAbstractClass (worüber ich nicht wirklich glücklich bin, da das Ding eigentlich auch Inhousesource ist)
 

CSHW89

Bekanntes Mitglied
Damit ich das richtig verstehe, mal nachgefragt: du möchtest also z.B. eine weitere Klasse "ListClass" erstellen, die die Methode "get" besitzt und eine unmodifizierbare Kopie der Liste zurückgeben, die dir die Klasse "SomeAbstractClass" zurückgibt?
Wenn das so ist, kann dies definitiv nicht ohne zusätzlichen Code in der Klasse "ListClass" passieren. Auch wenn dir "SomeAbstractClass.get" eine Liste zurückgibt, die Methode "Collections.unmodifiableCollection" macht dir darauf immer eine Collection. Die zusätzlichen Eigenschaften einer Liste hat diese unmodifizierbare Kopie nicht mehr.

Es gäbe aber zwei Möglichkeiten, die mir einfallen:
Java:
public abstract class CollectionClass<T, R extends Collection<T>> extends SomeAbstractClass<R> {
    public R get() {
        return makeUnmodifiable(super.get());
    }
    protected abstract R makeUnmodifiable(R collection);
}

public class ListClass<T> extends CollectionClass<T, List<T>> {
    protected List<T> makeUnmodifiable(List<T> collection) {
        return Collections.unmodifiableList(collection);
    }
}
... oder ...
Java:
public abstract class CollectionClass<T, R extends Collection<T>> extends SomeAbstractClass<R> {
    private UnaryOperator<R> converter;
    protected CollectionClass(UnaryOperator<R> converter) {
        this.converter = converter;
    }
    public R get() {
        return converter.apply(super.get());
    }
}

public class ListClass<T> extends CollectionClass<T, List<T>> {
    public ListClass() {
        super(Collections::unmodifiableList);
    }
}
Grüße
Kevin
 

SimProtect

Aktives Mitglied
Dass die untergeordneten Klassen noch etwas Code benötigen, ist mir klar. Hier war allerdings vorgesehen, die get() erneut zu überschreiben und stattdessen eben eine unmodfiableList o.Ä. zurückzugeben - also letztlich nichts anderes, als das, was Du vorgeschlagen hast - nur mit einer anderen Herangehensweise. (wobei ich die Deine ehrlich gesagt eleganter finde, als meine ursprüngliche :) )

Die hier so bezeichnete SomeAbstractClass gibt nicht generell eine Collection zurück, sondern bedient alle Arten von Objekten. Collections und co stellen hier lediglich komplexere Implementierungen dar. Somit gibt die get der Oberklasse lediglich vor, dass das ein Element des Typs zurückgegeben wird, auf welches SAC getypt wurde <- also in diesem Falle Collection<T>

Der zusätzliche Code hier wäre auch kein Problem, da die Elemente alle in unserem Framework liegen. Sollte ein Entwickler diese Klasse selbst erweitern wollen, so muss er eben auch damit umgehen, hier noch ein bisschen Hand anzulegen. Die in diesem Thread betrachteten Klassen werden als "fertiges Gesamtpaket" herausgegeben. (anders als andere Elemente des Frameworks, die dann eben erst konkret implementiert werden).

Danke übrigens auch für Deine Codebeispiel: Ich habe dadurch gemerkt, dass ich vergessen hatte, die CollectionClass abstract zu machen. Es wird dringend Zeit für ein paar Tage Urlaub -.-
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Generic-Problem. was meint ihr dazu? Allgemeine Java-Themen 4
krgewb Problem mit Umlauten und Eszett bei InputStream Allgemeine Java-Themen 3
Max246Sch Backtracking Problem Box Filler Allgemeine Java-Themen 6
NightVision402 VisualVM Startskript Problem Allgemeine Java-Themen 3
javaBoon86 Email Server Connection Problem Allgemeine Java-Themen 1
F Problem mit PDFBOX Library Allgemeine Java-Themen 1
A Java modul Problem Allgemeine Java-Themen 4
D Read JSON File Problem Allgemeine Java-Themen 9
urmelausdemeis Exception in thread "main" java.lang.Error: Unresolved compilation problem: Allgemeine Java-Themen 7
J Problem mit JasperReports Allgemeine Java-Themen 8
M log4j Problem mit jlink Allgemeine Java-Themen 19
8u3631984 Problem beim Mocken von Record Klassen Allgemeine Java-Themen 4
torresbig Website login Problem - Jsoup, wie bisher, klappt nicht! Allgemeine Java-Themen 31
P Selenium . getText Problem Allgemeine Java-Themen 9
A Jar zu Exe Problem Allgemeine Java-Themen 13
sserio Variablen Liste erstellt und ein Problem mit dem Index Allgemeine Java-Themen 6
S Folgendes Problem bei einem Programm Allgemeine Java-Themen 1
stormyark Problem beim Klassen erstellen Allgemeine Java-Themen 1
A Thread.sleep Problem Allgemeine Java-Themen 2
A Problem bei der Nachbarschafttest Allgemeine Java-Themen 11
Splayfer Problem: no main manifest attribute Allgemeine Java-Themen 3
G javamail Problem beim Empfangen von Nachrichten Allgemeine Java-Themen 3
Splayfer JDA Problem mit MessageCounter Allgemeine Java-Themen 0
Splayfer Problem mit BufferedWriter Allgemeine Java-Themen 3
F Streams als Alternative für dieses Problem ? Allgemeine Java-Themen 15
N Maven Problem mit Datenbanktreiber (H2 Embedded) Allgemeine Java-Themen 12
T Problem beim Umwandeln in eine Jar-Datei Allgemeine Java-Themen 3
B Einfach Elemente zweier Arraylisten kreuz und quer vergleichen, min und max Problem? Allgemeine Java-Themen 16
C ArrayList Problem Allgemeine Java-Themen 3
kev34 nim-Spiel problem Allgemeine Java-Themen 1
D Firebase retrieve data Problem, Child Element wird nicht angesprochen Allgemeine Java-Themen 0
G Welches Problem besteht bei den Typparametern? Allgemeine Java-Themen 5
temi Problem mit Aufrufreihenfolge bei Vererbung Allgemeine Java-Themen 3
Sumo_ow "ArrayIndexOutofBoundsException: 2" Array Problem Allgemeine Java-Themen 6
T PIM basierend auf netbeans via AnyDesk Problem Allgemeine Java-Themen 3
xGh0st2014 Problem mit Java Array Allgemeine Java-Themen 1
Kirby.exe Verständnis Problem bei Rucksack Problem Allgemeine Java-Themen 6
B Eclipse-Lombok-Problem Allgemeine Java-Themen 19
I Input/Output ObjectOutputStream - Problem Allgemeine Java-Themen 7
1 Multiple Choice Knapsack- Problem Allgemeine Java-Themen 2
kodela Problem mit strukturiertem Array Allgemeine Java-Themen 18
E Problem mit Gridlayout und Button Allgemeine Java-Themen 2
A Array Problem Allgemeine Java-Themen 8
bueseb84 Problem Allgemeine Java-Themen 0
S Problem mit Arrays Allgemeine Java-Themen 1
D Nullpointer Exception Problem Allgemeine Java-Themen 5
B Problem mit meinen Klassen Allgemeine Java-Themen 6
A HashMap Methode "get()"-Problem Allgemeine Java-Themen 28
J Problem beim Umstellen auf Java jdk 13 Allgemeine Java-Themen 3
J Problem bei Install java 13 Allgemeine Java-Themen 3
X Profitable Reise Problem Allgemeine Java-Themen 32
A Problem beim öffnen von Java-Installern Allgemeine Java-Themen 1
Dann07 Problem mit JavaMail API Allgemeine Java-Themen 26
J Problem beim Generischen Klassen und Interfaces Allgemeine Java-Themen 2
L Klassen Algorithmus für das folgende Problem entwickeln? Allgemeine Java-Themen 30
J Clear-Problem Allgemeine Java-Themen 10
B Problem zu einem Java Projekt Allgemeine Java-Themen 6
S JFileChooser Problem Allgemeine Java-Themen 4
M Traveling Salesman - MST Heuristik Problem Allgemeine Java-Themen 4
J Traveling Salesman Problem Allgemeine Java-Themen 14
E Java Editor Problem mit 2er Exceptions Allgemeine Java-Themen 12
C code oder Bibliotheken für 2-Center Problem Allgemeine Java-Themen 4
M Salesman Problem - Bruteforce Algorithmus Allgemeine Java-Themen 23
S Methoden Problem mit NullPointerException Allgemeine Java-Themen 9
Javafan02 Problem mit if-clause Allgemeine Java-Themen 17
J Lombok Problem mit Konstruktoren bei Verberbung Allgemeine Java-Themen 1
kodela Event Handling Problem mit der Alt-Taste Allgemeine Java-Themen 16
W Threads Problem Allgemeine Java-Themen 15
D (Verständnis-)Problem mit Unterklasse Allgemeine Java-Themen 4
S jserialcomm Problem Allgemeine Java-Themen 1
Flynn Thread-Problem... Allgemeine Java-Themen 2
J Generische Interface - Problem Allgemeine Java-Themen 3
G Problem beim GUI Allgemeine Java-Themen 9
L Applet Problem "security: Trusted libraries list file not found" ? Allgemeine Java-Themen 7
A OOP Problem beim Berechnen der größten Fläche eines Ringes Allgemeine Java-Themen 19
T Problem mit externen Datenbankzugriff über SSH Tunnel Allgemeine Java-Themen 4
F Problem beim Einlesen einer Textdatei Allgemeine Java-Themen 12
S Java OpenOffice Problem mit Windows-Benutzerwechsel Allgemeine Java-Themen 19
K Threads RAM Problem Allgemeine Java-Themen 20
P Operatoren Problem mit Zähler in recursiver Schleife Allgemeine Java-Themen 2
C Int Problem Allgemeine Java-Themen 8
C J2V8 NodeJs Java Bride Problem und Frage!?!? Allgemeine Java-Themen 1
J Problem bei Hashmap Key-Abfrage Allgemeine Java-Themen 4
C Webseiten Programm problem Allgemeine Java-Themen 5
M LocalDate Problem Allgemeine Java-Themen 4
J "Problem Objektorientierung" Allgemeine Java-Themen 20
geekex Problem Meldung! Was tun?! Allgemeine Java-Themen 19
T Klassen Override Problem Allgemeine Java-Themen 7
L Unbekanntes Problem Allgemeine Java-Themen 1
FrittenFritze Problem mit einer JComboBox, Event temporär deaktivieren Allgemeine Java-Themen 11
Blender3D Java Swing Programm Windows 10 Autostart Problem Allgemeine Java-Themen 2
F HTTPS Zertifikat Problem Allgemeine Java-Themen 3
M OpenCV KNearest Problem Allgemeine Java-Themen 0
Tommy Nightmare Project Euler: Problem 22 Allgemeine Java-Themen 2
C Abstrakte Klasse, lokale Variable-Problem Allgemeine Java-Themen 1
N Vererbung Design-Problem mit vorhandenen, von der Klasse unabhängigen Methoden Allgemeine Java-Themen 12
P Eclipse Projekt anlegen macht Problem Allgemeine Java-Themen 1
RalleYTN META-INF/services Problem Allgemeine Java-Themen 3
F Java Mail Problem: Authentifizierung wird nicht immer mitgeschickt Allgemeine Java-Themen 1
I Problem beim Aufrufen, von Objektmethoden/ -variablen Allgemeine Java-Themen 6

Ähnliche Java Themen

Neue Themen


Oben