Issue
I have this two classes, using generics:
public Response version1(Parameters params) {
Supplier<Response> s = () -> getResponse(params);
return unversioned (params, s);
}
public Response2 version2(Parameters params) {
Supplier<Response2> s = () -> getResponse2(params);
// s.get().getData(); Here, I am able to get the Data, because it knows it's from a Response2 class.
return unversioned (params, s);
}
These two generics are used for me to not have to duplicate every single line of code, as the methods are pretty much the same, just one line of code is different, which is the return type. So, when I call the generics:
private <T> T unversioned(Parameters parameters, Supplier<T> supplier) {
T result = supplier.get();
}
When I try to get the result.getData()
method, it does not understand. Because it does not infer the type. How can I do that?
Solution
What you could do is add bounds to the generic type of your unversioned
method.
private <T extends DataProvider> T unversioned(Parameters parameters, Supplier<T> supplier) {
// logic
}
This, however, requires you to have your response objects implement an interface:
public interface DataProvider {
/*
* Not sure what the return type of getData is, so used String for illustrative purposes
*/
String getData();
}
In case your response objects need to have different return values for getData
you could further generify the interface.
public interface DataProvider<T> {
T getData();
}
This requires a slight tweak of the unversioned
method:
private <T extends DataProvider<?>> T unversioned(Parameters parameters, Supplier<T> supplier) {
// logic
}
And you can now define your response objects as follows:
public class StringResponse implements DataProvider<String> {
@Override
public String getData() {
// logic
}
}
public class IntegerResponse implements DataProvider<Integer> {
@Override
public Integer getData() {
// logic
}
}
Answered By - Jeroen Steenbeeke
Answer Checked By - Candace Johnson (JavaFixing Volunteer)