I have a Cache object for persisting objects to disk, and the way I've implemented this causes me to have to use @SupressWarnings . I'm not a Java expert, but this seems like a code smell, and I'm wondering if there's a 'better' way to do what I'm doing here (for instance, somehow storing a Type when I write the cache, and reading this value to be able to instantiate a specific type?).
My Cache object looks like this (not-relevant code removed for brevity):
/**
* Write object o to cache file
*
* @param cacheName
* @param o
* Serializable object to write to cache
*/
public static void put(String cacheName, Serializable o) throws IOException {
FileOutputStream fos = new FileOutputStream(getHashedFileName(cacheName));
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(o);
fos.close();
}
/**
* Get an object from the cache. Caller should use exists() before calling
* here to make sure the cache item exists otherwise Exception will be
* thrown
*
* @param cacheName
* @return Object from cache
*/
public static Object get(String cacheName) throws CacheNotFoundException,
IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream(getHashedFileName(cacheName));
ObjectInputStream ois = new ObjectInputStream(fis);
Object o = ois.readObject();
return o;
}
Because get() can return any type of object, I now have to cast it back to the original type when I read from the cache. I'm wondering if I can avoid generating the warning in the first place:
class somethingDoingSomeWork {
/**
* Save all work done to the cache.
* @throws IOException
*/
public void saveToCache() throws IOException {
Cache.put(getCacheKey(), (MyObject<String>) summary);
}
/**
* Repopulate from cache
*/
@SuppressWarnings("unchecked")
public boolean loadFromCache() throws IOException, CacheNotFoundException,
ClassNotFoundException {
// Code removed, checking for existence of cache, etc.
// Cast required here, and this row generates unchecked warning
summary = (MyObject<String>) Cache.get(getCacheKey());
return true;
}
}
Edit: For people suggesting moving @SuppressWarnings
closer to the code, annotations can only be used on lines that are declarations, so this won't help me
Also using generics helps, but it appears to move the problem into the Cache.get()
method. The best solution appears to be this: http://www.velocityreviews.com/forums/t499693-how-do-you-prevent-unchecked-cast-warning-when-reading-from-objectinputstream.html
and I'm wondering if there's a 'better' way to do what I'm doing here (for instance, somehow storing a Type when I write the cache, and reading this value to be able to instantiate a specific type?)
Use generics here. If you have
public <String, P extends Serializable> R get( String key);
public <String, P extends Serializable> void put( String key, R value);
I am not pointing to already existing Cache implementations. Like Guava, those support cache anyways, but I blieve you want to improve this code.
At the last resort, One big thing is to always keep @SupressWarnings as close as possible to the code causing it.