I have a method that should only accept a Map
whose key is of type String
and value of type Integer
or String
, but not, say, Boolean
.
For example,
map.put("prop1", 1); // allowed
map.put("prop2", "value"); // allowed
map.put("prop3", true); // compile time error
It is not possible to declare a Map as below (to enforce compile time check).
void setProperties(Map<String, ? extends Integer || String> properties)
What is the best alternative other than declaring the value type as an unbounded wildcard
and validating for Integer
or String
at runtime?
void setProperties(Map<String, ?> properties)
This method accepts a set of properties to configure an underlying service entity. The entity supports property values of type String
and Integer
alone. For example, a property maxLength=2
is valid, defaultTimezone=UTC
is also valid, but allowDuplicate=false
is invalid.
You can’t declare a type variable to be either of two types. But you can create a helper class to encapsulate values not having a public constructor but factory methods for dedicated types:
If you are using 3rd party libraries with map builders, you don’t need the
map
methods, they’re convenient for short maps only. With this pattern, you may call the method likeSince there are only the two
Value
factory methods forint
andString
, no other type can be passed to the map. Note that this also allows usingint
as parameter type, so widening ofbyte
,short
etc. toint
is possible here.