Reputation: 4681
I don't think that there is a way that is efficient (if at all) of doing this, but I figured I'd ask in case someone else knows otherwise. I'm looking to create my own Cache/lookup table. To make it as useful as possible, I'd like it to be able to store generic objects. The problem with this approach is that even though you can make a Collections.unmodifiableMap, immutableMap, etc
, these implementations only prevent you from changing the Map itself. They don't prevent you from getting the value from the map and modifying its underlying values. Essentially what I'd need is for something to the effect of HashMap<K, ? extends Immutable>
, but to my knowledge nothing like this exists.
I had originally thought that I could just return a copy of the values in the cache in the get method, but since Java's Cloneable
interface is jacked up, you cannot simple call
public V getItem(K key){
return (V) map.get(k).clone();
}
Upvotes: 6
Views: 906
Reputation: 122449
There is no formal concept of "mutability" or "immutability" in the language. The compiler cannot tell whether a type is "mutable" or "immutable". To determine whether something is immutable, we humans have to examine every field and method of the class, and reason through the behavior of the methods to discover that none of them will alter the state of the object, then we call it "immutable". But there is no difference from the perspective of the language.
Upvotes: 1
Reputation: 425083
Your thinking is good, and you're right that there's no built-in way of handling immutability.
However, you could try this:
interface Copyable<T> {
T getCopy();
}
Then override the get()
method to return copies instead of the value itself;
class CopyMap<K, V extends Copyable<V>> extends HashMap<K, V> {
@Override
public V get(Object key) {
return super.get(key).getCopy();
}
}
Then it's up to the implementation to return a copy of itself, rather than this
(unless the class itself is immutable). Although you can't enforce that in code, you would be within your rights to publicly humiliate the programmer that doesn't conform.
Upvotes: 5
Reputation: 16496
There are other options for object cloning in Java: Making a copy of an object Dynamically?
Be aware though that deep cloning any object might be dangerous. The objects stored in this map must be i.e. isolated from each other, to make sure that whole object graph won't be copied when returning a single entry.
Upvotes: 1
Reputation: 38541
I'm looking to create my own Cache/lookup table.
Why not use Guava's cache?
The problem with this approach is that even though you can make a Collections.unmodifiableMap, immutableMap, etc, these implementations only prevent you from changing the Map itself. They don't prevent you from getting the value from the map and modifying its underlying values.
This is not something any collection can enforce for you. You need to make the classes themselves immutable. There is a hacky approach using Reflection (which can also be used to make a class mutable!), but really, you should avoid this and simply create classes that are immutable.
Upvotes: 2