一个抽象Java类,其侦听器在其回调中使用具体类

一个抽象Java类,其侦听器在其回调中使用具体类,java,generics,Java,Generics,我想要一个这样的抽象Java类: abstract class AbstractFoo<F extends AbstractFoo<F, L>, L extends FooListener<F, L>> { private final Class<L> listenerClass; protected AbstractFoo(Class<L> listenerClass) { this.listenerClass = l

我想要一个这样的抽象Java类:

abstract class AbstractFoo<F extends AbstractFoo<F, L>, L extends FooListener<F, L>> {
  private final Class<L> listenerClass;
  protected AbstractFoo(Class<L> listenerClass) {
    this.listenerClass = listenerClass;
  }

  interface FooListener<F extends AbstractFoo<F, L>, L extends FooListener<F, L>> {
    void callback(F foo);
  }

  // Bar might implement FooListener, but I don't control it,
  // so I have no guarantee
  public void externalMethod(Bar bar) {
    if (listenerClass.isInstance(bar)) {
      L listener = listenerClass.cast(bar);

      listener.callback(this); // does not compile
    }
  }
}
抽象类AbstractFoo{
私人期末班监听器班;
受保护的AbstractFoo(类listenerClass){
this.listenerClass=listenerClass;
}
界面监听器{
无效回调(F foo);
}
//Bar可能会实现傻瓜监听器,但我无法控制它,
//所以我不能保证
public void externalMethod(Bar){
if(listenerClass.isInstance(bar)){
L listener=listenerClass.cast(条形);
listener.callback(this);//不编译
}
}
}

listener.callback(this)无法编译,因为无法保证
F
的类型相同。是否有可能以某种方式保证
F
this
的超类型?

您试图做的是使用泛型在Java中模拟SELF类型。请参阅或了解执行此操作的一些方法。但是,无法强制F(或自类型)实际上是相同的类型,例如(请参见ConcreteFoo2的类型参数):


无法保证您的
AbstractFoo
实例是
Foo
的实例。我们也不知道
Bar
是如何定义的。如果
AbstractFoo实现了Foo
,那么您可能可以做一些事情,这样类型系统就知道
这个
可以满足第一个参数是
F
类型的要求。对不起,我修复了我的泛型声明。另外,我也不能保证如何定义
Bar
,所以我不能这样做任何假设谢谢!今天上午我考虑了<代码> GETSelf()/Case>解决方案。
static class Bar implements FooListener<ConcreteFoo, Bar> {

    @Override
    public void callback(final ConcreteFoo foo) {
        // TODO Auto-generated method stub

    }

}

static class ConcreteFoo2 extends AbstractFoo<ConcreteFoo, Bar> {

    protected ConcreteFoo2(final Class<Bar> listenerClass) {
        super(listenerClass);
    }

}

static class ConcreteFoo extends AbstractFoo<ConcreteFoo, Bar> {

    protected ConcreteFoo(final Class<Bar> listenerClass) {
        super(listenerClass);
    }

}
static final class Bar implements FooListener<ConcreteFoo> {

    @Override
    public void callback(final ConcreteFoo foo) {
        // TODO Auto-generated method stub

    }

}

static final class ConcreteFoo extends AbstractFoo<ConcreteFoo> {

    protected ConcreteFoo(final Class<? extends FooListener<ConcreteFoo>> listenerClass) {
        super(listenerClass);
    }

    @Override
    protected ConcreteFoo getSelf() {
        return this;
    }

}

static abstract interface FooListener<FOO extends AbstractFoo<FOO>> {

    void callback(FOO abstractFoo);
}

static abstract class AbstractFoo<SELF extends AbstractFoo<SELF>> {

    private final Class<? extends FooListener<SELF>> listenerClass;

    protected AbstractFoo(final Class<? extends FooListener<SELF>> listenerClass) {
        this.listenerClass = listenerClass;
    }

    protected abstract SELF getSelf();

    // Bar might implement FooListener, but I don't control it,
    // so I have no guarantee
    public void externalMethod(final Bar bar) {
        if (listenerClass.isInstance(bar)) {
            final FooListener<SELF> listener = listenerClass.cast(bar);

            listener.callback(getSelf()); // compiles
        }
    }
}