通用类型的通用工厂函数

时间:2018-05-14 15:42:59

标签: java generics factory-method

我知道这个问题非常相似,但并不完全相同 java parameterized generic static factory

到目前为止,我还没有找到这个确切的案例,也无法弄清楚我想做什么甚至可以做到。所以,假设这个几乎是最小的例子:

public class Test {
  public static interface Interface<T, P> {
    T get(P param);
  }

  public static class StringIntInterface implements Interface<String, Integer> {
    public String get(Integer param) {
      String[] options = new String[] { "hello", "cruel", "world" };
      int p = param > 0 ? param : -param;
      return options[p % 3];
    }
  }

  public static class IntStringInterface implements Interface<Integer, String> { 
    public Integer get(String param) {
      return param.length();
    }
  }

  public static class InterfaceProvider {
    public Interface<?, ?> getInterface(String name) {
      if (name.equals("int")) {
        return new StringIntInterface();
      } else if (name.equals("string")) {
        return new IntStringInterface();
      }
      return null;
    }
  }

  public static void main(String... args) {
    InterfaceProvider ip = new InterfaceProvider();
    StringIntInterface si = (StringIntInterface)ip.getInterface("int");
    IntStringInterface is = (IntStringInterface)ip.getInterface("string");
    System.out.println(si.get(5));
    System.out.println(is.get("a somewhat long string, whatever"));
  }
}

这是我到目前为止编译和工作的唯一版本,有趣的是(对我而言)没有未经检查的转换警告......

我想我清楚自己想做什么,但有没有办法摆脱InterfaceProvider::getInterface() Test::main()InterfaceProvider::getInterface()用法中的演员阵容?我已经尝试了各种方法使public <R, P, T extends Interface<R, P>> T getInterface(String name); public <R, P, T extends Interface<R, P>> T getInterface(String name, Class<R> retType, Class<P> paramType); public <T extends Interface<?, ?>> T getInterface(String name); 成为通用方法,所有这些方法都会导致编译错误。到目前为止,那些尝试过的签名是:

T

因为我希望P的参数InterfaceInterface没有任何界限,并且只想为git commit-tree -m "take theirs" -p HEAD -p branchB 'branchB^{tree}' git reset --hard 36daf519952 # is the output of the prev command 的任何实现实例化一个InterfaceProvider我没有选择将任何类型参数移动到InterfaceProvider类...

有什么想法吗?或者这根本不可能?

1 个答案:

答案 0 :(得分:0)

您不应在StringIntInterface中使用IntStringInterfacemain。接口是定义一个规范,让用户不需要关心实现。如果您需要了解具体实施StringIntInterface,为什么需要工厂?所以它应该是

Interface<String, Integer> si = (Interface<String, Integer>) ip.getInterface("int");
Interface<Integer, String> is = (Interface<Integer, String>)ip.getInterface("string");

现在,所有人都尝试签名

public <R, P, T extends Interface<R, P>> T getInterface(String name);
Interface<String, Integer> si = ip.getInterface("int");
Interface<Integer, String> is = ip.getInterface("string");

但请注意,虽然它有效(你不需要做明确的演员),但每件事都没有改变。它仍然不是类型安全的。