2010-04-24 50 views
0

我對Java相對比較陌生,習慣於C#中的泛型,所以用這段代碼掙扎了一下。基本上我需要一個通用的方法來獲取存儲Android偏好的鍵,而這個代碼雖然很醜,但它適用於布爾型而不是整型,當它拋出ClassCastException時。誰能告訴我爲什麼這是錯誤的,也許幫助我改進整個例程(使用通配符?)?如何從int轉換爲泛型類型Integer?

public static <T> T getPreference(Class<T> argType, String prefKey, T defaultValue, 
     SharedPreferences sharedPreferences) { 

    ... 

    try { 
     if (argType == Boolean.class) { 
      Boolean def = (Boolean) defaultValue; 
      return argType.cast(sharedPreferences.getBoolean(prefKey, def)); 
     } else if (argType == Integer.class) { 
      Integer def = (Integer) defaultValue; 
      return argType.cast(new Integer(sharedPreferences.getInt(prefKey, def))); 
     } else { 
      AppGlobal.logWarning("getPreference: Unknown type '%s' for preference '%s'. Returning default value.", 
        argType.getName(), prefKey); 
      return defaultValue; 
     } 
    } catch (ClassCastException e) { 
     AppGlobal.logError("Cast exception when reading pref %s. Using default value.", prefKey); 
     return defaultValue; 
    } 
} 

我調用的代碼是:

 mAccuracy = GlobalPreferences.getPreference(Integer.class, prefKey, mAccuracy, sharedPreferences); 

這裏是getInt()Android的代碼:

public int getInt(String key, int defValue) { 
     synchronized (this) { 
      Integer v = (Integer)mMap.get(key); 
      return v != null ? v : defValue; 
     } 
    } 

我已經試過各種方法 - 使用本地INT,鑄造一個Integer,但沒有用。

+0

'mAccuracy'是什麼類型? – JRL 2010-04-24 16:38:44

+0

請注意,我已經解決了這個問題。請參閱下面的答案。首選項本身是以字符串的形式存儲的,它是錯誤的Android代碼。謝謝 – 2010-04-24 16:41:57

+0

你不能爲這個方法返回一個'Integer'數據類型,對嗎?我的意思是,該方法的簽名表示「int」,而不是「整數」.... – Nitrodist 2010-06-09 20:46:18

回答

0

事實證明,我試圖讀取存儲爲一個字符串,所以劇組異常是從Android的代碼不是我內傳來的偏好。謝謝你的幫助。但是,因爲我是一個Java新手,如果你認爲我的日常工作有任何問題,請教我一個更好的方法。

+0

如果您嘗試使用與getType方法相對應的類型不同的名稱獲取首選項,那麼API特別聲明來自'SharedPreferences'的所有'getType'方法都會拋出'ClassCastException'。 – JRL 2010-04-24 16:45:07

+0

沒錯。我的下一個問題是你如何獲得一個ListPreference,它的值是一個int數組。 – 2010-04-24 16:55:24

0

可能,我建議:

Integer i = new Integer(42); 
+0

除非我錯了你的問題和你需要完成什麼,這應該工作,因爲輸入是一個'int'。 – 2010-04-24 15:59:36

+0

對不起,這是行不通的。那是我的原始代碼。實際上,我將編輯樣本以表明這一點。謝謝 – 2010-04-24 16:14:46

+0

我糾正了我的示例感謝,並顯示Android源被調用。 – 2010-04-24 16:17:17

0

嘗試界定與採取不同類型的默認名稱相同的一堆功能,並讓編譯器看着辦吧。在處理類型時,Java真的會牽扯你的雙手,尤其是原始類型。

public function int getPreference(String key , int missing) { return sharedPreferences.getInt(key , missing); } 
public function boolean getPreference(String key , boolean missing) { return sharedPreferences.getBoolean(key , missing); } 
public function String getPreference(String key , String missing) { return sharedPreferences.getString(key , missing); } 

編輯:

如果你想獲得一個對象(而不是原始的),不分類型,你可以使用:

public function Object getPreference(String key , Object missing) { return sharedpreferences.contains(key) ? sharedPreferences.getAll().get(key) : missing; } 

如果你想獲得一個特定的類型像int,無論存儲什麼內容,都可以使用:

public function int getPreference(String key , int missing) { 
    int result = missing; 
    Object value = sharedpreferences.contains(key) ? sharedPreferences.getAll().get(key) : null; 
    if (value instanceof Integer) result = ((Integer)value).intValue(); 
    if (value instanceof Boolean) result = ((Boolean)value).booleanValue() ? 1 : 0; 
    // repeat for every other primitive wrapper type you care about 
    return result; 
} 

如果您試圖獲得結果只有當它是某種類型,你可以使用類似:

public function Object getPreference(Class inRequire , String key , Object missing) { 
    Object value = sharedpreferences.contains(key) ? sharedPreferences.getAll().get(key) : null; 
    if (!(value instanceof inRequire)) { 
     value = null; 
    } 
    return (value == null) ? missing : value; 
} 
+0

我認爲這就是泛型的全部內容:)如果可能,我寧願使用泛型。但如果我不能,我會按你的建議去做。謝謝 – 2010-04-24 16:23:17

+0

Java不像其他語言那樣靈活,原語不是對象,因此它們不能混合在返回類型或函數參數中。你可以返回一個Object或一個特定的基元,如int或boolean,但它必須在編譯時決定。 – drawnonward 2010-04-25 02:13:31

+0

謝謝 - 這很有用,但它仍然返回一個對象,不是嗎?不是強類型的對象。 – 2010-04-25 14:09:31