通用类型的通用工厂函数
Generic factory function for generic type
我知道这个问题与
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);
因为我希望 Interface
的参数 T
和 P
没有任何限制,并且只需要为 [=17 的任何实现实例化一个 InterfaceProvider =] 我没有将任何类型参数移动到 InterfaceProvider class...
的选项
有什么想法吗?或者这根本不可能?
您不应在 main
中使用 StringIntInterface
或 IntStringInterface
。接口是定义一个规范,让用户不需要关心实现。如果你需要知道具体实现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");
但是请注意,尽管它有效(您不需要进行显式转换),但一切都没有改变。它仍然不是类型安全的。
我知道这个问题与 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);
因为我希望 Interface
的参数 T
和 P
没有任何限制,并且只需要为 [=17 的任何实现实例化一个 InterfaceProvider =] 我没有将任何类型参数移动到 InterfaceProvider class...
有什么想法吗?或者这根本不可能?
您不应在 main
中使用 StringIntInterface
或 IntStringInterface
。接口是定义一个规范,让用户不需要关心实现。如果你需要知道具体实现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");
但是请注意,尽管它有效(您不需要进行显式转换),但一切都没有改变。它仍然不是类型安全的。