我有一个Cache对象用于将对象持久化到磁盘,而我实现这一点的方式导致我必须使用@SupressWarnings。我不是Java专家,但这看起来像代码味道,我想知道是否有一种'更好'的方式来做我在这里做的事情(例如,当我写缓存时以某种方式存储一个Type,并读取此值以能够实例化特定类型?)。
我的缓存对象如下所示(为简洁起见,删除了不相关的代码):
/**
* 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;
}
因为get()可以返回任何类型的对象,所以当我从缓存中读取时,我现在必须将其强制转换回原始类型。我想知道我是否可以首先避免产生警告:
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;
}
}
编辑:对于建议将@SuppressWarnings
移近代码的人,注释只能在声明的行上使用,所以这对我没有帮助
同样使用泛型有帮助,但它似乎将问题转移到Cache.get()
方法。最佳解决方案似乎是:http://www.velocityreviews.com/forums/t499693-how-do-you-prevent-unchecked-cast-warning-when-reading-from-objectinputstream.html
答案 0 :(得分:2)
假设密钥和值均为Serializable
,您可以使用这些签名
public <R extends Serializable, P extends Serializable> R get( P key);
public <R extends Serializable, P extends Serializable> void put( P key, R value);
答案 1 :(得分:1)
我想知道是否有'更好'的方法来做我在这里做的事情(例如,在我写缓存时以某种方式存储一个Type,并且读取这个值以便能够实例化一个特定的类型? )
在这里使用泛型。如果你有
public <String, P extends Serializable> R get( String key);
public <String, P extends Serializable> void put( String key, R value);
我没有指出已经存在的Cache实现。像Guava一样,那些支持缓存,但我很想你改进这段代码。
最后一招,一件大事就是始终让@SupressWarnings尽可能接近导致它的代码。
答案 2 :(得分:0)
无论你喜欢什么
//此处需要施放,此行生成未经检查的警告
summary =(MyObject)Cache.get(getCacheKey());
它将生成未经检查的警告,以避免这个更好的选项来生成CollectionHelper类并在CollectionHelper类中生成未经检查的警告。并使用CollectionHelper类从该类返回对象。
例如,
public class CollectionsHelper {
/**
*
* @param list
* of List type
* @return list - List of MyObject type
*/
@SuppressWarnings("unchecked")
public static List<MyObject> getMyObjects(List list) {
return (List<MyObject>) list;
}
}
并以这种方式使用
List<MyObject> objList = CollectionsHelper.getMyObjects(Cache.get(getCacheKey());
您无需在服务或实现类中添加@SupressWarnings。