- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Umgang mit Generics bei EditorValue
Hallo,
Es geht um das Interface EditorValue<T>.
Um direkt einzusteigen, hier ein Code-Auszug:
// key enthaelt einen Bezeichner einer Editor-Komponentefor (String key : myMap.keySet()) {
// (!) EditorValue is a raw type.EditorValue editorValue = data.get(key).getEditor();
try {
// (!) Type safety: The method set(Language, Object) belongs to the raw type EditorValueeditorValue.set(masterlanguage, scriptData.get(key).getEditor().get(masterlanguage));
} catch (InvalidValueException e) {
//...}
}
Die beiden mit :smileyalert: markierten Stellen werden von Eclipse berechtigermaรen bemรคngelt, weil man sich รผber Generics hinwegsetzt. Sie werden ja durch das Interface EditorValue<T> hier gefordert.
Da wir รผber eine Collection von Bezeichnern von Editor-Komponenten iterieren, ist jedoch der Typ des konkreten EditorValue unklar, so dass man nicht auf bestimmte konkrete EditorValue-Typen (z.B. TextEditorValue) casten darf.
Meine Fragen:
Gibt es einen Weg, um diesen Fall elegant zu lรถsen, ohne auf @SuppressWarnings oder eine "hundertfache" instanceof-Behandlung zurรผckgreifen zu mรผssen?
Besten Dank
Georg
- Labels:
-
Developers
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
รber "editorValue.getValueType().cast(..)", am besten รผber eine Hilfsmethode:
public <T> void setValue(final EditorValue<T> editorValue, final Language language, final Object value) throws InvalidValueException {
editorValue.set(language, editorValue.getValueType().cast(value));}
Hier kann natรผrlich eine ClassCastException fliegen, wenn die aufrufende Stelle eine ungรผltigen Werte-Typ liefert. Es muss also der Aufrufer sicherstellen, das nur korrekte Kombinationen benutzt werden.
Zu Generics kann ich folgende Web-Seite empfehlen: http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ja die Angelika kenn' ich, fรผr mich das weiblich Pendant zu Josh Bloch ;-).
Danke fรผr den Tipp, ich werde ihn ausprobieren.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry,
ich muss hier nochmal einhaken und nachhaken.
Folgender Code:
Listable bodies = page.getChildren(Body.class);
for (Body body : bodies) {
Listable<Section> sections = body.getChildren(Section.class);
...
}
Jetzt ist es so, dass getChildren einen Rรผckgabewert Listable<Section> hat.
Jedoch ist Section an und fรผr sich generisch (ein Umstand รผbrigens, den ich nicht verstehe, denn was fรผr unterschiedliche Dinge enthรคlt so eine Section? In der Regel ist es auรerdem kein beliebiges "T" fรผr Section<T>, sondern ein Section<T extends SectionTemplate).
Aber zurรผck zur Frage:
Dieser Code lรคsst sich nur dann ohne Warnung anfรผhren, wenn man "@SuppressWarnings("rawtypes")" verwendet.
Wie unschรถn! Und das vermutlich nur, weil getChildren eine ungenerische Section zurรผckliefert.
Vermutlich habe ich mir die Antwort jetzt schon selbst vorweg genommen, daher:
Wรคre es mรถglich die API so zu aktualisieren, dass getChildren ebenfalls generisch arbeitet? In dem Zug wรคre es fรผr mich auch ausreichend, hier statt einem "Listable" eine echte List<Section<T>> zurรผckzubekommen.
Danke... und jetzt dรผrft ihr mich teern und federn.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Im Codebeispiel fehlt der generische Typ fรผr das erste Listable:
Listable<Body> bodies = page.getChildren(Body.class);
Damit sollte auch die Warnung verschwinden.
Die Typisierung von Section bezieht sich auf das Template (es gibt Sections fรผr Absatztemplates und fรผr Tabellentemplates).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hallo Peter,
Die Typisierung von Section bezieht sich auf das Template (es gibt Sections fรผr Absatztemplates und fรผr Tabellentemplates).
Ah - vor dem Hintergrund macht die Typisierung an der Stelle schon mehr Sinn. Sehe gerade dass SectionTemplate durch TableTemplate erweitert wird.
Hier nochmal der SourceCode
Listable<Body> bodies = page.getChildren(Body.class);
for (Body body : bodies) {
// @SuppressWarnings("rawtypes")
Listable<Section> sections = body.getChildren(Section.class);
// ^^^^^^^^
for (Section<?> section : sections) {..}
}
Die markierte Zeile wird nachwievor gelb mit dem Hinweis auf "Section is a raw type." bemรคngelt. Meines Erachtens liegt das daran, dass body.getChildren keinen eine einfache Section, zurรผckgibt, jedoch nicht Section<T>.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hallo,
Georg Stach schrieb:
Die markierte Zeile wird nachwievor gelb mit dem Hinweis auf "Section is a raw type." bemรคngelt. Meines Erachtens liegt das daran, dass body.getChildren keinen eine einfache Section, zurรผckgibt, jedoch nicht Section<T>.
das ist technisch auch leider nicht anders mรถglich, weil hier die Klasse als Parameter den Rรผckgabetyp bestimmt. Und Klassen kann man so in Java nicht parameterisieren.
Gruร
Stefan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
das ist technisch auch leider nicht anders mรถglich, weil hier die Klasse als Parameter den Rรผckgabetyp bestimmt. Und Klassen kann man so in Java nicht parameterisieren
Wรผrde ich so nicht unterschreiben. Eine Signatur wie diese sollte es tun:
public <T> Listable<? extends T> getChildren(Class<? extends T> clazz)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Das ist sicherlich richtig. Parameterisiert die Klasse natรผrlich nicht, aber es wรผrde das "Warning" Problem lรถsen. Eine Kleinigkeit fehlt noch in der Signatur, die dann so aussรคhe (betrifft im รผbrigen auch weitere API-Methoden dieser Art):
public <T extends StoreElement> Listable<? extends T> getChildren(Class<? extends T> clazz)
Der รnderung entgegen steht allerdings, dass dadurch zahlreiche Code-Stellen quellinkompatibel werden wรผrden, was im Rahmen der API natรผrlich nicht machbar ist (das รผbliche API Problem). Fรผr den Gewinn (ein Warning weniger) lohnt die รnderung jedenfalls nicht.
Gruร
Stefan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
.. dass dadurch zahlreiche Code-Stellen quellinkompatibel ..
Ja, das sehe ich ein.
Dennoch, vielleicht ist es als Anregung hilfreich. Denn gerade weil es nicht die einzige Stelle in der API ist, die inkonsistent ist, kรถnnte man hier รผber eine Anpassung nachdenken.
Dann natรผrlich mit einem MajorRelease (ich will keine Nummern nennen )...

