2012-11-23 231 views
-1

我有下面的類Java泛型鑄造<?>

public class DBField<T> 
{ 
    protected String fieldName; 
    protected FieldConverter c; 
    protected T value; 
    protected DataObject dataObject; 

    public T getValue() 
    { 
    return value; 
    } 

    public void setValue(T value) 
    { 
    this.value = value; 
    } 

    public DBField(DataObject dataObject, String fieldName, FieldConverter c) 
    { 
    this.fieldName = fieldName; 
    this.c = c; 
    this.dataObject = dataObject; 
    } 
} 

T被認爲是布爾型,浮點,字符串等

protected void ValuesToFields(List<Object> values, List<DBField<?>> fields) throws Exception 
    { 
    if (values.size() != fields.size()) 
     throw new Exception("Length does not match."); 
    for (int i = 0; i < values.size(); i++) 
    { 
     Class valueClass = values.get(i).getClass(); 
     Class fieldClass = fields.get(i).getValue().getClass(); 
     if (valueClass.equals(fieldClass)) 
     { 
     fields.get(i).setValue(values.get(i)); 
     } 
     else 
     throw new Exception("type mismatch"); 
    } 
    } 

對象也應該包含布爾,浮點數,字符串等

這段代碼的問題是

fields.get(i).setValue(values.get(i)); 

語法檢查器告訴我,我需要將values.get(i)(to?我猜測)。我該怎麼做呢?我已經嘗試過valueClass.cast(values.get(i)),但沒有運氣。

回答

1

爲了使您的代碼是安全的,對於每個ivalues的第i個元素必須是一個實例DBField的類型參數,它是fields的第i個元素。你的代碼並不能保證這一點,事實上,沒有辦法在Java中聲明它們以確保相應元素之間的這種關係是真實的。由於類型擦除,你甚至不能在運行時檢查元素是否正確,因爲給定一個字段,你不知道它的類型參數。所以必須有一些不加控制的演員,我們必須相信這些論點是正確的。

做到將每個字段轉換爲DBField<Object>最簡單的事情:

((DBField<Object>)fields.get(i)).setValue(values.get(i)); 

這是一種說法「相信我們,我們知道,這個領域可以採取任何Object」,因此可以採取任何類型的值。這有點說謊,因爲我們知道應該有一些字段的類型參數不是Object,但是由於我們必須進行某種不受控制的投射,所以這種「不安全的投射」並不比其他解決方案差。或者,如果你不想做這種可以說是可疑的轉換,更合理的方法是編寫一個私有幫助器方法 - 一個「包裝助手」 - 它明確地命名該類型的參數場,使我們能夠簡單地轉換爲價值這一類型:

private <T> static void ValueToField(Object value, DBField<T> field) { 
    field.setValue((T)value); 
} 

//... 
ValueToField(values.get(i), fields.get(i)); 

請注意,這裏的演員陣容也未經檢查的演員。這種方法的缺點是它需要編寫額外方法的開銷。

P.S.您的支票與valueClassfieldClass不是很好。首先,如果某個字段的值目前爲null,則會導致空指針異常。此外,DBField<T>的值是T的任何實例,其實際類可以是T的子類;所以如果你用這個來檢查,可能會導致不好的結果。如果DBField包含類別爲T的類對象,那麼它可能是最好的,因此它可以用於檢查。此外,您不應該將相等與值的實際類進行比較,因爲T的子類也可以工作,所以您應該檢查fieldClass.isInstance(values.get(i))

0

if(values.get(i) instanceof valueClass)

+0

這將如何幫助?只要在該線之前放置一個if就不會解決這條線沒有被修改的錯誤。問題是setValue需要布爾值,字符串等,而values.get(i)是一個對象。 – cdbeelala89

+0

我的意思是用你的'if'替換我的。我認爲這可能是Syntax檢查器的一個問題,即檢查兩個類彼此相等是不夠的。 – EMMERICH

-1

您有List<Object>

你應該有一個List<DBField<Object>>與之相匹配的,或者改變您的第一個列表List<?>

+0

這沒有幫助。問題是setValue需要布爾值,字符串等,而values.get(i)是一個對象。 – cdbeelala89

+0

我會說要更改您的列表參數列表,這基本上意味着同樣的事情,語法警告應該消失 – njzk2