我正在尝试编写一个request.getParameter("user_id");
构建器。其中一个构造函数将允许客户端指定他们希望构建的Map
的类型
Map
目的是应该可以使用以下方法构造构建器的实例:
public class MapBuilder<K, V> {
private Map<K, V> map;
/**
* Create a Map builder
* @param mapType the type of Map to build. This type must support a default constructor
* @throws Exception
*/
public MapBuilder(Class<? extends Map<K, V>> mapType) throws Exception {
map = mapType.newInstance();
}
// remaining implementation omitted
}
或
MapBuilder<Integer, String> builder = new MapBuilder<Integer, String>(LinkedHashMap.class);
似乎构造函数参数的类型签名当前不支持此功能,因为上面的行会导致“无法解析构造函数”编译错误。
如何更改构造函数,使其仅接受实现MapBuilder<Integer, String> builder = new MapBuilder<Integer, String>(HashMap.class);
的类?
答案 0 :(得分:10)
使用Supplier
代替Class
:
public MapBuilder(Supplier<? extends Map<K, V>> supplier) {
map = supplier.get();
}
然后可以这样称呼它:
MapBuilder<Integer, Integer> builder = new MapBuilder<>(LinkedHashMap::new);
这也更安全,因为Class<Map>
可能没有默认构造函数,这会引发错误(这不是响应性很强的代码)
答案 1 :(得分:2)
以下将起作用:
public MapBuilder(Class<? extends Map> mapType) throws Exception {
map = mapType.newInstance();
}
答案 2 :(得分:2)
问题是LinkedHashMap.class
是
Class<LinkedHashMap>
而不是类似
Class<LinkedHashMap<Integer, String>>
这些类型也是不可转换的类型(因此您无法进行转换),并且无法获取后者的实例。
您可以做的是将构造函数更改为
public MapBuilder(Class<? extends Map> mapType) throws Exception
泛型在运行时被删除,因此在运行时所有Map
的行为都将与Map<Object, Object>
一样。因此,您要构造的类使用原始类型都没关系。
不建议使用Class::newInstance
。使用
mapType.getConstructor().newInstance()