对不起标题,但用简单的话很难解释问题。 上课:
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类定义的所有者,因此我无法更改它。我可以延伸但不知何故。 我该怎么做才能强迫这种关系?
答案 0 :(得分:0)
我认为你不能因为类型擦除而使用纯Generics做到这一点......但是根据你为实现目标而愿意写的多少,这可能是一种潜力(尽管如此)凌乱的解决方案。在不了解更多细节的情况下,很难说这是否会涵盖您的所有用例。
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);
}
}