如果您使用类似Guava的
TypeToken
,那么您可以以类型安全的方式进行操作,但仍然无法检查。
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>
。这是不安全的。
您可以这样做:
ExpressionMap em = new ExpressionMap();
em.put(List.class, ListStringExpression::new);
Expression ex =
em.get(List.class).apply(Arrays.asList(1, 2, 3));
所以这是可能的,但要注意一些注意事项。
另请参见什么是原始类型,为什么不能使用它?
put
方法来实现这个。 - njzk2