Generischer Rückgabetyp aus einer generischen Methode

8

Betrachten Sie eine generische Methodendefinition wie folgt:

%Vor%

Funktioniert perfekt, um einen beliebigen Objekttyp zu erhalten, bis Sie ein generisches Objekt wie List & lt; String & gt; versuchen. Der einzige Weg, wie ich es zum Laufen bringen konnte, war so:

%Vor%

Aber das erfordert eine zusätzliche Besetzung, die den Zweck der Methode beseitigt. Gibt es eine Möglichkeit, List<String>.class oder etwas Ähnliches zur Verfügung stellen zu können? (Ich weiß, dass diese Art der Löschung verhindert, dass List<String> existiert, aber vielleicht gibt es einen Weg, dies zu tun).

Hinweis: Damit es funktioniert, meine ich, ohne eine Art Sicherheitswarnung zu haben. Ich bin mir bewusst, dass der Code funktionieren würde, wie es ist, aber es ist nicht typsicher.

    
Juru 17.02.2015, 09:49
quelle

2 Antworten

7

Dies kann nicht typsicher ausgeführt werden, ohne den Downstream-Code ( context.get() ) zu ändern, da der generische Typ zur Laufzeit gelöscht wird. Tatsächlich wird derzeit das Argument clazz überhaupt nicht verwendet: Sie könnten dieses Argument einfach löschen, und die Methode würde sich identisch verhalten, da die Umwandlung in (T) aufgrund des Löschens derzeit keine Operation ist. Ihr aktueller Code ist nicht typsicher, auch für nicht-geniale Klassen.

Wenn Sie also nicht auf die Sicherheit achten und nur vermeiden möchten, dass der Client-Code umgewandelt wird, können Sie einfach das letzte Argument löschen und einmal Warnungen für die Methode unterdrücken.

Wenn Sie die Sicherheit eingeben möchten, können Sie die generischen Typinformationen mit Super-Typ-Token versehen: Guava's TypeToken funktioniert und ist leicht verfügbar (IMO jedes Java-Projekt sollte bereits Guava verwenden).

Es werden jedoch nachgeschaltete Änderungen an Ihrem Code erforderlich sein, da Sie die Typinformationen erfassen müssen, wenn Objekte hinzugefügt werden, und sie überprüfen, wenn sie herauskommen. Du hast den Code für deine Context -Klasse nicht geteilt. Daher ist es schwer zu sagen, ob das möglich ist, aber auf jeden Fall möchtest du Folgendes:

%Vor%

Grundsätzlich kennen Sie den generischen Typ aller Objekte in Ihrer Parameterzuordnung und überprüfen ihn zur Laufzeit mit einem "generic aware cast". Ich habe oben Context.put() nicht eingeschlossen, aber Sie müssten die Typinformationen erfassen, wenn der Parameter hinzugefügt wurde.

Sie haben immer noch @SuppressWarnings("unchecked") , aber hier ist es nachweislich typsicher, da Sie die Typinformationen pflegen (im Innersten vieler generischer Klassen finden Sie nachweisbar sichere Umwandlungen, so dass sie nicht immer vermieden werden können) im richtigen Code).

    
BeeOnRope 17.02.2015, 10:08
quelle
1

Wie Sie bereits gesagt haben, gibt es nichts wie List<String>.class . Wenn Sie also nur Parameter ohne Umwandlungen lesen möchten, können Sie Folgendes verwenden:

%Vor%

Ich nehme an, dass Ihr Kontext auch Object zurückgibt und Sie für diese eine Methode trotzdem Typ-Sicherheitsüberprüfungen unterdrücken müssen.

    
sodik 17.02.2015 10:04
quelle

Tags und Links