2012-11-23 64 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