Home > other >  How can I infer the type of the method on Java dynamically?
How can I infer the type of the method on Java dynamically?

Time:07-12

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?

CodePudding user response:

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
  }
}
  • Related