Restrict a generic Class parameter to classes that implement Map
Use a Supplier
instead of a Class
:
public MapBuilder(Supplier<? extends Map<K, V>> supplier) {
map = supplier.get();
}
Which then can be called like this:
MapBuilder<Integer, Integer> builder = new MapBuilder<>(LinkedHashMap::new);
This is also safer, because a Class<Map>
could have no default constructor, which would throw an error (which is not very responsive code)
The following will work:
public MapBuilder(Class<? extends Map> mapType) throws Exception {
map = mapType.newInstance();
}
The problem is that LinkedHashMap.class
is
Class<LinkedHashMap>
and not something like
Class<LinkedHashMap<Integer, String>>
These are also inconvertible types (so you can't cast it) and there's no way to get an instance of the latter.
What you can do is change the constructor to
public MapBuilder(Class<? extends Map> mapType) throws Exception
Generics are erased at run-time so at run-time all Map
s will behave just like Map<Object, Object>
anyway. Therefore it doesn't matter that the class you're constructing from is using the raw type.
By the way, Class::newInstance
is deprecated. Use
mapType.getConstructor().newInstance()