不确定这是否可行;我承认我并不像我希望的那样擅长仿制药。
基本上,我想创建一个类的地图 - >功能 其中用于键的类是函数输入的类,如此(非法律语法):
chkconfig
所以,如果我这样做:
public static Map<Class<T>,Function<T,Expression>> STUFF = new HashMap<>();
{
STUFF.put(List.class, ListExpression::new);
STUFF.put(String.class, StringExpression::new);// this constructor must take string
}
它适合我的类型。
答案 0 :(得分:6)
无法做到。每次你想要Map<Class<T>, SomeType<T>>
时,即将一个类与参数化类型相关联,以某种方式与键中的类相关,就无法完成。这是因为密钥类型Class<T>
必须按照Map<K, V>
定义在所有条目之间共享。
剩下的是具有Map<Class<?>, SomeType<?>>
的实际替代方法,将此地图封装在私有字段中,并在将项目放入地图时检查约束。像
public class StuffManager {
private final Map<Class<?>, Consumer<?>> stuff = new HashMap<>();
public <T> void register(Class<T> key, Consumer<? super T> val) {
stuff.put(key, val);
}
}
答案 1 :(得分:3)
如果您使用Guava&#39; TypeToken
之类的东西,那么您可以以类型安全的方式执行此操作但仍未选中。
window.swaggerUi = new SwaggerUi({
// ...
sorters : "alpha" // or sorter I've tried both
});
您可以使用class ExpressionMap {
private final Map<TypeToken<?>, Function<?, Expression>> m =
new HashMap<>();
<T> void put(TypeToken<T> type, Function<T, Expression> f) {
m.put(type, f);
}
<T> Function<T, Expression> get(TypeToken<T> type) {
@SuppressWarnings("unchecked")
final Function<T, Expression> f =
(Function<T, Expression>) m.get(type);
return f;
}
}
static ExpressionMap stuff = ExpressionMap();
static {
stuff.put(new TypeToken<List>() {}, ListExpression::new);
stuff.put(new TypeToken<String>() {}, StringExpression::new);
}
代替Class
,但问题是它会因泛型类型而崩溃。
如果你有
TypeToken
您无法ListStringExpression extends Expression {
ListStringExpression(List<String> l) {}
}
,因此所有Class<List<String>>
都会被ListOfSomeTypeExpression::new
混为一谈。这不安全。
你可以这样做:
Function<List, Expression>
所以它可能但要注意警告。
答案 2 :(得分:1)
不,您无法使用默认的Map
界面执行此操作。
但是你当然可以“隐藏”立面背后的地图 - 一个为用户提供特定方法的自定义界面或类:
public <T> Function<T, Expression> getFunction(Class<T> key) {
// implement using generic Map<Class<?>, Function<?, Expression>
}
甚至:
public Expression apply(Object param);