Java中类型泛型的复杂情况

Java中类型泛型的复杂情况,java,generics,Java,Generics,我希望Java中有一个类型,它以某种方式引用自身 确切地说,我想要一个可以有侦听器的命令类: public abstract class GenericCommand<T> implements Future<T> { // ... private final List<GenericCommandListener<GenericCommand<T>>> listeners = new ArrayList<>

我希望Java中有一个类型,它以某种方式引用自身

确切地说,我想要一个可以有侦听器的命令类:

public abstract class GenericCommand<T> implements Future<T> {
    // ...
    private final List<GenericCommandListener<GenericCommand<T>>> listeners = new ArrayList<>();

    @SuppressWarnings("unchecked")
    public void addListeners(
            GenericCommandListener<GenericCommand<T>>... listeners) {
        this.listeners.addAll(Arrays.asList(listeners));
    }

    private void onValueAvailable() {
        for (GenericCommandListener<GenericCommand<T>> listener : listeners) {
            listener.onValueAvailable(this);
        }
    }
}
此类命令的目的是发送到设备并产生特定类型的结果

现在,我希望能够重写我的
GenericCommand
,以便它实现一种特殊类型的命令,可能是
FooCommand
,它会生成一个

public class QueryValueCommand extends GenericCommand<Double> {
}
因此从它派生的
queryvalue命令
接受
GenericCommandListener


如果您像这样实现
GenericCommandListener

  public interface GenericCommandListener<T> {
    public <U extends GenericCommand<T>> void onValueAvailable(U theCmd);
  }

这有帮助吗?

正如Aruistante所建议的,类
GenericCommand
必须以这种方式依赖于自身:

public abstract class GenericCommand<C extends GenericCommand<C, T>, T> implements Future<T> {
    // ...
    private final List<GenericCommandListener<C, T>> listeners = new ArrayList<>();

    @SuppressWarnings("unchecked")
    public void addListeners(
            GenericCommandListener<C, T>... listeners) {
        this.listeners.addAll(Arrays.asList(listeners));
    }

    private void onValueAvailable() {
        for (GenericCommandListener<C, T> listener : listeners) {
            listener.onValueAvailable((C) this);
        }
    }
}
公共抽象类GenericCommand实现未来{
// ...
私有最终列表侦听器=新的ArrayList();
@抑制警告(“未选中”)
公共空添加侦听器(
GenericCommandListener…侦听器){
this.listeners.addAll(Arrays.asList(listeners));
}
私有void onValueAvailable(){
for(GenericCommandListener侦听器:侦听器){
onValueAvailable((C)this);
}
}
}
侦听器类也必须通过以下方式进行修改:

interface GenericCommandListener<C extends GenericCommand<C,T>, T>  {
    public void onValueAvailable(C theCmd);
}
接口GenericCommandListener{
可用价值上的公共无效(C.D);
}
现在,您可以声明:

public class QueryValueCommand extends GenericCommand<QueryValueCommand, Double>
公共类queryvalue命令扩展了GenericCommand
你可以写:

QueryValueCommand command = new QueryValueCommand();
GenericCommandListener<QueryValueCommand, Double> listener = ...;

command.addListeners(listener);
QueryValueCommand=newqueryvaluecommand();
GenericCommandListener侦听器=。。。;
addListeners(监听器);

这里需要两种类型;正在使用的
GenericCommand
类的类型,以及该
GenericCommand
的返回值。换句话说,完整类型说明符应该是
,而
QueryCommand
将满足
T=Double
。事实上,您对
QueryComannd
的类定义正好说明了这一点;它不是一个
GenericCommand
,它
扩展了GenericCommand
。唉,不,因为我希望
onValueAvailable()
函数接收命令对象,而不仅仅是值本身。
onValueAvailable
确实接收命令对象
U
,而不是值
T
,因为
U
扩展了
GenericCommand
。哦,对不起,误读了。但是现在我不能再创建lambda了,因为我现在得到了“
非法lambda表达式:GenericCommand类型的onValueAvailable方法是generic
”。。。不知何故,我必须在那里插入这两种类型…是在
addListener
方法上吗?是的,我喜欢使用lambdas作为侦听器。但另一个解决方案似乎对我有帮助。谢谢你的回答。唉,我必须让每个子类都提供自己的名称,如
C
,最好让它们成为
final
。这对我来说似乎是多余的,而且总是必须提供
C
T
。演员阵容也不太漂亮。但无论如何,这似乎是最好的选择,所以我实现了它,现在它似乎起作用了。
interface GenericCommandListener<C extends GenericCommand<C,T>, T>  {
    public void onValueAvailable(C theCmd);
}
public class QueryValueCommand extends GenericCommand<QueryValueCommand, Double>
QueryValueCommand command = new QueryValueCommand();
GenericCommandListener<QueryValueCommand, Double> listener = ...;

command.addListeners(listener);