2012-01-23 39 views
2

我有一個用於將對象保存到磁盤的緩存對象,並且我實現這個的方式導致我不得不使用@SupressWarnings。我不是Java專家,但是這看起來像是一種代碼味道,我想知道是否有一種'更好'的方式來做我在這裏做的事情(例如,當我編寫緩存時以某種方式存儲Type,並閱讀這個值,以便能夠實例化一個特定的類型?)。如何避免必須使用@SuppressWarnings(「unchecked」)?

我的緩存對象看起來像這樣(沒有相關的代碼簡潔,刪除):

/** 
* 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

+3

您是否知道您可以使用'@SuppressWarnings(「unchecked」)'作爲語句而不是整個方法? – adarshr

+0

也許你可以使用泛型? – hage

+0

不相關的,但你應該讓你的緩存一個實例,然後使用常規方法,而不是靜態方法。 – Luciano

回答

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儘可能接近導致它的代碼。

+0

@SuppressWarnings不能應用於某一行或區塊,對嗎?只有一種方法/課程? – mozboz

+0

Huhh看看這個http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/SuppressWarnings.html Doent它說你可以在這些地方有@supressWarning @Target(value = {TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})現在在你的代碼中,你可以在這裏放置supresswarning,比如//在這裏需要Cast,並且這一行產生未經檢查的警告 @SuppressWarnings(「unchecked」) summary = MyObject )Cache.get(getCacheKey());//如果你嘗試這將工作 –

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); 
+0

爲了確保我理解此作品的原因
MyObject摘要; summary = Cache.get(someKey); 這裏的第二行允許編譯器確定類型R,因此不需要強制轉換? (對不起,這裏完成markdown失敗) – mozboz

+0

此外,用這種方法我不必在get()中更改此行:Object o = ois.readObject();對此:R o =(R)ois.readObject();剛剛將問題轉移到其他地方? – mozboz

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使用它。

相關問題