I am working on a (simple) caching solution where a service can request a Cache object from the Cache Map. A Cache object works in much the same way as a Map object, with a key and value and methods for accessing and storing objects.
I came up with the following solution, but as you can see, it contains a cast (because get () cannot know what types of nested object should be).
private final Map<String, Cache<?, ?>> caches = new HashMap<String, Cache<?, ?>>(); public <K, V> Cache<K, V> getOrCreateCache(String identifier) { if (caches.containsKey(identifier)) { return (Cache<K, V>) caches.get(identifier); } else { Cache<K, V> cache = new CacheImpl<K, V>(); caches.put(identifier, cache); return cache; } } private void test() { Cache<String, String> strCache = getOrCreateCache("string cache"); strCache.set("key", "value"); }
Now, my questions are:
- Is this a “safe” approach as long as cool views are handled properly? (probably catch them and pack them in a special exception class)
- Is there a "safe" alternative? One with generics, if at all possible, because I like them and don't like ghosts.
- (not directly related) Is it thread safe? I guess not, but then I'm not a slicer. Is it enough to just make the whole method synchronized, or will it (with half a dozen clients) cause too much overhead / locks? Is there a neat solution for this?
Edit: Woo, many answers, thanks! Editing here to describe the strangeness I found by actually testing this:
Cache<String, String> someCache = service.getOrCreateCache(cacheIdentifier); someCache.set("asdf", "sdfa"); Cache<String, Integer> someCacheRetrievedAgain = service.getOrCreateCache(cacheIdentifier); System.out.println(someCacheRetrievedAgain.get("asdf")); // prints "sdfa". No errors whatsoever. Odd.
source share