Java-有界泛型作为有界泛型方法的输入

Java-有界泛型作为有界泛型方法的输入,java,generics,bounded-wildcard,Java,Generics,Bounded Wildcard,给定一个泛型类型Result,并使用以下部分实现 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 */ } /* ot

给定一个泛型类型
Result
,并使用以下部分实现

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 */

}
上述示例失败,并显示给定的类型不匹配错误消息


我已经尝试更改.mergeWith的签名,以接受更窄的
结果,而不是
结果根据结果的合并声明,当且仅当T是s的子类型时,您可以将结果与结果合并

在聚合方法中,左的类型参数是节点的某个未知子类,右的类型参数也是节点的某个未知子类。不能保证right的type参数是left的子类

如果您尝试以下方法:

public <S extends Node, T extends S> Result<? extends Node> aggregate(Result<S> left, Result<T> right) {
    Result<? extends Node> temp = left.mergeWith(right);
    /** do stuff*/
    return temp;
}

公共结果问题来自于相互独立的
捕获。不要在类定义中使用
捕获。使用泛型类型标识符:

public class SomeVisitor<T extends Node> implements Visitor<Result<T>> {

    public Result<FileNode> visitFile() { }

    /* ... */

    protected Result<T> aggregate(Result<T> left, Result<T> right) {
        Result<T> tempResult = left.mergeWith(right);
    }
}
public类SomeVisitor实现Visitor{
公共结果visitFile(){}
/* ... */
受保护的结果聚合(结果左、结果右){
结果tempResult=left.mergeWith(右);
}
}

这是一种非常巧妙(但非常Java-y)的解决方法。不幸的是,我正在实现的接口将聚合描述为
T聚合(T左,T右)也许我应该用以下信息来补充这个问题:)对不起!不确定这是否可以不铸造。。。然而,看起来你只需要投一次。tempLeft.mergeWith(右)应该有效。
实现访问者
不会编译,因为泛型类型标识符的边界必须在实现类上定义,而不是在interface.oops上定义。我会解决的。我打算将类声明为
SomeVisitor
您能显示
Visitor.visitFile()
签名吗?此外,它还将有助于展示如何实际使用
SomeVisitor
。@shmosel done。希望能有帮助。
FileContext fileCtx = someOtherService.acquireFileContext();
SomeVisitor visitor = new SomeVisitor();
Result<FileNode> fileNodeResult = visitor.visitFile(fileCtx);
// process the result
@SuppressWarnings("unchecked")
Result<Node> tempLeft   = (Result<Node>) left;
@SuppressWarnings("unchecked")
Result<Node> tempRight  = (Result<Node>) right;
Result<Node> tempResult = tempLeft.mergeWith(tempRight);
public <S extends Node, T extends S> Result<? extends Node> aggregate(Result<S> left, Result<T> right) {
    Result<? extends Node> temp = left.mergeWith(right);
    /** do stuff*/
    return temp;
}
public class SomeVisitor<T extends Node> implements Visitor<Result<T>> {

    public Result<FileNode> visitFile() { }

    /* ... */

    protected Result<T> aggregate(Result<T> left, Result<T> right) {
        Result<T> tempResult = left.mergeWith(right);
    }
}