eine generische Art Result<T>
mit der folgenden Teil Umsetzung BeiJava - generic Bounded als Eingabe begrenzt generische Methode
public class Result<T> {
/* fields, ctor, etc... */
public Result<T> mergeWith(Result<? extends T> other) {
/* fiddle with this and other (acting as producer) and return */
}
/* other methods */
}
und der Verwendung in einem Visitor ...
Schnittstelle:
public interface Visitor<T> {
T visitFile(FileContext ctx);
T aggregate(T left, T right);
/* ... */
}
Umsetzung:
public class SomeVisitor implements Visitor<Result<? extends Node>> {
// this works fine, as I can return subtypes of 'Node'
@Override
public Result<FileNode> visitFile() { }
/* ... */
@Override
public Result<? extends Node> aggregate(Result<? extends Node> left,
Result<? extends Node> right) {
// This line completely blows up.
Result<? extends Node> tempResult = left.mergeWith(right);
// Expected type: 'Option<? extends capture of ? extends Node>'
// Have type: 'Option< ? extends Node>'
}
Callsite von SomeVisitor
:
FileContext fileCtx = someOtherService.acquireFileContext();
SomeVisitor visitor = new SomeVisitor();
Result<FileNode> fileNodeResult = visitor.visitFile(fileCtx);
// process the result
Das obige Beispiel nicht mit den gegebenen Typ-Mismatch-Fehlermeldungen.
Ich habe bereits versucht, die Signatur von .mergeWith zu ändern, um die viel schmalere Result<T>
statt einer Result<? extends T>
zu akzeptieren. Dies führt zu einem erwarteten Typ von Result<capture of ? extends Node>
in diesem Beispiel. Und breche es an anderen Stellen, wo <? extends T>
der richtige generische Typ ist, da in diesem Fall other
ein Produzent ist.
Die einzige Lösung, die tatsächlich funktioniert, wirft sowohl left
nach unten und right
-Result<Node>
, sie verschmilzt und dann zurück:
@SuppressWarnings("unchecked")
Result<Node> tempLeft = (Result<Node>) left;
@SuppressWarnings("unchecked")
Result<Node> tempRight = (Result<Node>) right;
Result<Node> tempResult = tempLeft.mergeWith(tempRight);
Das ist nicht nur hässlich und temporäre Variablen einführt, ist es auch nicht schöner bekommen, wenn Ich inline die Casts.
Ich würde gerne wissen, ob das ist nur die hässliche Wahrheit über Java-Generika und die Grenze davon oder wenn ich etwas falsch mache.
Können Sie die 'Visitor.visitFile()' Signatur anzeigen? Es würde auch helfen zu zeigen, wie 'SomeVisitor' tatsächlich benutzt wird. – shmosel
@smossel erledigt. Ich hoffe es hilft. – baeda