抱歉这个标题,但这个问题很难用简单的语言解释。 上课:
public abstract class SimpleAssembler
<DI extends IIdBean, DO extends DomainObject, VO extends VOBase>
implements Assembler<DI, DO, VO> {...}
我想强制DO和DI之间的连接,以便DO始终必须实现DI。我试图让它像这样工作:
public abstract class SimpleAssembler
<DI extends IIdBean, DO extends DomainObject & DI, VO extends VOBase>
implements Assembler<DI, DO, VO> {...}
但这不会编译。另一个问题是我不是 DomainObject 类定义的所有者,因此我不可能更改它。不过我可以以某种方式延长。 我可以做什么来强制这种关系?
由于类型擦除,我认为您无法使用纯泛型来做到这一点......但是根据您愿意编写多少代码来实现您的目标,这可能是一个潜在的(尽管很混乱)解决方案。在不了解更多细节的情况下,很难说这是否能涵盖您的所有用例。
import java.io.Serializable;
interface Assembler<DI, DO, VO> {
/* ??? not given ??? */
void acceptsBean(DI bean);
void acceptsDomain(DO domain);
}
interface VOBase {
/* ??? not given ??? */
}
interface IIdBean<T extends Comparable<T> & Serializable> {
/* as given */
}
class DomainObject {
/* third-party class, cannot be altered */
}
abstract class AbstractIdBeanDomainObject
<T extends Comparable<T> & Serializable, I extends IIdBean<T>>
extends DomainObject {
private final Class<I> interfaceType;
protected AbstractIdBeanDomainObject(Class<I> beanInterface) {
super();
if (beanInterface == null
|| !beanInterface.isAssignableFrom(this.getClass())) {
throw new IllegalStateException(
"This class must implement the specified bean type.");
}
interfaceType = beanInterface;
}
final I asBean() {
return interfaceType.cast(this);
}
}
interface IIntIdBean extends IIdBean<Integer> {
/* ... */
}
class MyIntIdBean implements IIntIdBean {
/* ... */
}
class MyIntDomainObject extends AbstractIdBeanDomainObject<Integer, IIntIdBean> {
MyIntDomainObject() {
super(IIntIdBean.class);
}
}
class NotSoSimpleAssembler
<T extends Comparable<T> & Serializable,
DI extends IIdBean<T>,
DO extends AbstractIdBeanDomainObject<T, DI>,
VO extends VOBase>
implements Assembler<DI, DO, VO> {
@Override
public void acceptsBean(DI bean) { }
@Override
public void acceptsDomain(DO domain) { acceptsBean(domain.asBean()); }
}
public class StackOverflow22555608 {
public static final void main(String[] args) {
VOBase base = new VOBase() { /* ??? */ };
IIntIdBean idBean = new MyIntIdBean();
AbstractIdBeanDomainObject<Integer, IIntIdBean> domainObj =
new MyIntDomainObject();
Assembler<IIntIdBean, AbstractIdBeanDomainObject<Integer, IIntIdBean>, VOBase> asm =
new NotSoSimpleAssembler<>();
asm.acceptsBean(idBean);
asm.acceptsDomain(domainObj);
}
}