I have these interfaces and classes in a java (17) application:
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);
}
}
Whole system is ok except the call to setDetail()
in useWithApple()
method of ComplexGenericUser
class. The compiler error states that no instance of type variable (T) exists so that AppleSurvey conforms to ISurvey<T>
. How can I resolve this?
AppleSurveyDetails
implements ISurveyDetails<AppleSurvey>
. As written, your setDetail
method expects AppleSurveyDetails
to implement ISurveyDetails<ISurvey<AppleSurveyDetails>>
, not ISurveyDetails<AppleSurvey>
.
I think correctly parameterizing setDetail
requires two type parameters, one for the survey and one for the details:
<D extends ISurveyDetails<S>, S extends ISurvey<D>>
void setDetail(S survey, Supplier<D> detailMaker) {
var detail = detailMaker.get();
detail.setSurvey(survey);
survey.setDetails(detail);
}
You'll also need to fix your setDetail
call - the supplier should just be AppleSurveyDetails::new
, not () -> AppleSurveyDetails::new
.