I'm trying to write a Map
builder. One of the constructors will allow the client to specify the type of Map
they wish to build
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
}
The intent is that it should be possible to construct instances of the builder with:
MapBuilder<Integer, String> builder = new MapBuilder<Integer, String>(LinkedHashMap.class);
or
MapBuilder<Integer, String> builder = new MapBuilder<Integer, String>(HashMap.class);
It seems that the type signature of the constructor argument doesn't currently support this, because the line above causes a "Cannot resolve constructor" compilation error.
How can I change my constructor so that it accepts classes that implement Map
only?
Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class.
Bounded Type Parameters There may be times when you'll want to restrict the kinds of types that are allowed to be passed to a type parameter. For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is what bounded type parameters are for.
A class definition can have more than one type parameter.
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With