我在 java (17) 应用程序中有这些接口和类:
public interface ISurvey<T extends ISurveyDetails<? extends ISurvey<T>>> {
void setDetails(T details);
}
public interface ISurveyDetails<T extends ISurvey<? extends ISurveyDetails<T>>> {
void setSurvey(T survey);
}
public class AppleSurvey implements ISurvey<AppleSurveyDetails> {
@Override
public void setDetails(AppleSurveyDetails details) {
}
}
public class AppleSurveyDetails implements ISurveyDetails<AppleSurvey> {
@Override
public void setSurvey(AppleSurvey survey) {
}
}
public class ComplexGenericUser {
<T extends ISurveyDetails<ISurvey<T>>> void setDetail(ISurvey<T> survey, Supplier<T> detailMaker) {
var detail = detailMaker.get();
detail.setSurvey(survey);
survey.setDetails(detail);
}
void useWithApple() {
var appleSurvey = new AppleSurvey();
setDetail(appleSurvey, () -> AppleSurveyDetails::new);
}
}
除了在
setDetail()
类的useWithApple()
方法中调用ComplexGenericUser
之外,整个系统都正常。编译器错误指出no instance of type variable (T) exists so that AppleSurvey conforms to ISurvey<T>
。我该如何解决这个问题?
AppleSurveyDetails
实现ISurveyDetails<AppleSurvey>
。为了与您的 setDetail
方法兼容,AppleSurveyDetails
必须实现 ISurveyDetails<ISurvey<AppleSurveyDetails>>
,而不是 ISurveyDetails<AppleSurvey>
。
我认为正确参数化
setDetail
需要两种类型参数,一种用于调查,一种用于详细信息:
<Details extends ISurveyDetails<Survey>, Survey extends ISurvey<Details>>
void setDetail(Survey survey, Supplier<Details> detailMaker) {
var detail = detailMaker.get();
detail.setSurvey(survey);
survey.setDetails(detail);
}
您还需要修复您的
setDetail
电话 - 供应商应该只是 AppleSurveyDetails::new
,而不是 () -> AppleSurveyDetails::new
。
那么你需要更多仿制药:)
这是固定代码:
public interface ISurvey<S extends ISurvey<S, D>, D extends ISurveyDetails<S, D>> {
void setDetails(D details);
}
public interface ISurveyDetails<S extends ISurvey<S, D>, D extends ISurveyDetails<S, D>> {
void setSurvey(S survey);
}
public class AppleSurvey implements ISurvey<AppleSurvey, AppleSurveyDetails> {
@Override
public void setDetails(AppleSurveyDetails details) {
}
}
public class AppleSurveyDetails implements ISurveyDetails<AppleSurvey, AppleSurveyDetails> {
@Override
public void setSurvey(AppleSurvey survey) {
}
}
public class ComplexGenericUser {
<S extends ISurvey< S, D>, D extends ISurveyDetails<S, D>> void setDetail(S survey, Supplier<D> detailMaker) {
var detail = detailMaker.get();
detail.setSurvey(survey);
survey.setDetails(detail);
}
void useWithApple() {
var appleSurvey = new AppleSurvey();
Supplier<AppleSurveyDetails> tSupplier = AppleSurveyDetails::new;
setDetail(appleSurvey, tSupplier);
}
}