Suppose I have a class of the sort:
public class MyMap<K, V> implements Map<Set<K>, V> {
...
}
and I'd like to be able to enforce synchronisation on it. One way is to internally synchronise the methods (perhaps with the synchronized keywords), but if I intend it for more general usage, then it might be better to use external synchronisation, perhaps with the Collections.synchronizedMap() method.
The problem arises in the class where I try to implement this: suppose I have the following class:
public class Foo {
MyMap<String, Object> _myMap;
public Foo() {
_myMap = Collections.synchronizedMap(new MyMap<String, Object>());
}
}
On line 4 of the class, I get the error "Type mismatch: cannot convert from Map< Set < String>, Object> to MyMap< String, Object>". Eclipse suggests that I do one of two things: either add a cast to MyMap< String, Object>, or change the type of _myMap to Map< Set < String>, Object>. However, I obviously do not want to do the latter, since the whole point of using MyMap rather than Map is so that I can take advantage of the additional features I have implemented in MyMap. Then, when I try to add the cast as they suggest, so that the line now looks like
_myMap = (MyMap<String, Object>) Collections.synchronizedMap(new MyMap<String, Object>);
I get the following error when the code actually executes:
java.lang.ClassCastException: java.util.Collections$SynchronizedMap cannot be cast to ****.MyMap
It appears that the synchronizedMap() is downcasting(?) the MyMap to its "true" type, which is Map< Set< String>, Object>>, and then not allowing me to cast it back to a MyMap, which is what type I passed into synchronizedMap().
Is there any way around these to hack synchronizedMap to work with this kind of class? If not, what might be a recommended method of achieving external or synchronisation?
Perhaps as a follow-up question, is this method of implementing an interface where the type parameters are not simple types (for example the nontrivial Set< K> in the first Map parameter) commonly used in practice? Can the implementing class (MyMap in this case) ever be parametrised with anything other than simple types -- in other words, even if one is implementing something like Map< Set< K>, V>, can the implementing class ever have something other than < K, V> as its parameters (additional unused parameters notwithstanding)?
On a completely unrelated side note, does anyone know how I can get around the weird tag capturing (so that I don't have to put spaces like "Map< K, V>"), even when I enclose it with blocks?
Foohave a constructor forMyMap? is it supposed to be aFooconstructor?